Merge branch 'PMP-Locate-GF-old' into PMP-Locate-GF

This commit is contained in:
Mael Rouxel-Labbé 2019-07-01 11:28:25 +02:00
commit f68141a6d3
75 changed files with 7565 additions and 4265 deletions

View File

@ -254,15 +254,9 @@ The main function illustrates the access to the `id()` field.
\section BGLTriangulations Triangulations as Models of the Boost Graph Concept
Triangulations have vertices and faces, allowing for a direct translation
as a graph. An edge is defined as a pair of a face handle and the
index of the edge.
Particular care has to be taken with the infinite vertex and its incident
edges. One can either use a
<a href="https://www.boost.org/libs/graph/doc/filtered_graph.html">boost::filtered_graph</a>
in order to make the infinite edges
invisible, or one can have a property map that returns an infinite length
for these edges.
A complete list can be found in the documentation of \link BGLT2GT boost::graph_traits \endlink.
as a graph. A halfedge is defined as a pair of a face handle and the
index of the edge. A complete list can be found in the documentation
of \link BGLT2GT boost::graph_traits \endlink.
A classical example for an algorithm that is a combination of
computational geometry and graph theory is the <I>Euclidean Minimum
@ -291,7 +285,7 @@ use the property map returned by the call `get(boost::vertex_index,ft)`.
This property map assumes that the vertex has a
member function `id()` that returns a reference to an int.
Therefore \cgal offers a class `Triangulation_vertex_base_with_id_2`.
It is in the users responsibility to set the indices properly.
It is in the user's responsibility to set the indices properly.
The example further illustrates that the graph traits also works
for the Delaunay triangulation.

View File

@ -0,0 +1,45 @@
namespace CGAL {
/*!
\ingroup PkgBGLHelper
The class `Triangulation_face_base_with_id_2` is a model of the
concept `TriangulationFaceBase_2`, the base face of a
2D-triangulation. It provides an integer field that can be used to
index faces for \sc{Bgl} algorithms.
Note that the user is in charge of setting indices correctly before
running a graph algorithm.
\tparam TriangulationTraits_2 is the geometric traits class
and must be a model of `TriangulationTraits_2`.
\tparam TriangulationFaceBase_2 must be a face base class from which
`Triangulation_face_base_with_id_2` derives. It has the default
value `Triangulation_face_base_2<TriangulationTraits_2>`.
\cgalModels `TriangulationFaceBase_2`
\sa `CGAL::Triangulation_face_base_2`
*/
template< typename TriangulationTraits_2, typename TriangulationFaceBase_2 >
class Triangulation_face_base_with_id_2 : public TriangulationFaceBase_2 {
public:
/// \name Access Functions
/// @{
/*!
Returns the index.
*/
int id() const;
/*!
Returns a reference to the index stored in the face.
*/
int& id();
/// @}
}; /* end Triangulation_face_base_with_id_2 */
} /* end namespace CGAL */

View File

@ -4,6 +4,7 @@ PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - CGAL and the Boost Graph Library"
INPUT += ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/Euler_operations.h \
${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/iterator.h \
${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/helpers.h \
${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/generators.h \
${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/selection.h \
${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/split_graph_into_polylines.h \
${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/boost/graph/copy_face_graph.h \

View File

@ -546,7 +546,12 @@ Methods to read and write graphs.
\cgalPkgPicture{emst-detail.png}
\cgalPkgSummaryBegin
\cgalPkgAuthors{Andreas Fabri, Fernando Cacciola, Philipp Moeller, and Ron Wein}
\cgalPkgDesc{This package provides a framework for interfacing \cgal data structures with the algorithms of the Boost Graph Library, or \sc{BGL} for short. It allows to run graph algorithms directly on \cgal data structures which are model of the \sc{BGL} graph concepts, for example the shortest path algorithm on a Delaunay triangulation in order to compute the Euclidean minimum spanning tree. Furthermore, it introduces several new graph concepts describing halfedge data structures.}
\cgalPkgDesc{This package provides a framework for interfacing \cgal data structures
with the algorithms of the Boost Graph Library, or \sc{BGL} for short.
It allows to run graph algorithms directly on \cgal data structures which are model
of the \sc{BGL} graph concepts, for example the shortest path algorithm
on a Delaunay triangulation in order to compute the Euclidean minimum spanning tree.
Furthermore, it introduces several new graph concepts describing halfedge data structures.}
\cgalPkgManuals{Chapter_CGAL_and_the_Boost_Graph_Library,PkgBGLRef}
\cgalPkgSummaryEnd
\cgalPkgShortInfoBegin
@ -593,6 +598,7 @@ user might encounter.
\cgalCRPSection{Helper Classes}
- `CGAL::Triangulation_vertex_base_with_id_2`
- `CGAL::Triangulation_face_base_with_id_2`
- `CGAL::Arr_vertex_index_map`
- `CGAL::Arr_face_index_map`
- `CGAL::HalfedgeDS_vertex_max_base_with_id`

View File

@ -150,30 +150,29 @@ and `CGAL::Triangulation_hierarchy_2`
so that they are model of the graph concepts
`BidirectionalGraph`, `VertexAndEdgeListGraph`, and `FaceListGraph`.
The mapping between vertices and edges of the triangulation and the
Only finite simplices exist when viewed through the scope of these graph traits classes.
The infinite vertex, halfedges, edges, and faces will thus not appear when looping around a border
vertex, or walking through the faces container.
The mapping between vertices, edges, and faces of the triangulation and the
graph is rather straightforward, but there are some subtleties. The
value type of the \sc{Bgl} iterators is the vertex or edge descriptor,
whereas in \cgal all iterators and circulators are also handles and
hence have as value type Vertex or Edge.
The graph traits class for triangulations does not distinguish between
finite and infinite vertices and edges. As the edge weight computed
with the default property map of \sc{Bgl} algorithms (obtained with
`get(t, boost::edge_weight)`) is the length of the edge,
the edge weight is not well defined for infinite edges. For algorithms
that make use of the edge weight, the user must therefore
define a <A HREF="https://www.boost.org/libs/graph/doc/filtered_graph.html">`boost::filtered_graph`</A> or pass a property map to the
algorithm that returns "infinity" for infinite edges.
| Member | Value | Description |
| :----------------------- | :----: | :---------- |
| `vertex_descriptor` | `Triangulation::Vertex_handle` | Identify vertices in the graph. |
| `edge_descriptor` | `unspecified_type` | Identify edges in the graph. It is constructible from and convertible to `Triangulation::Edge`. It is not a simple typedef, but a proper class, because in an undirected graph the edges `(u,v)` and `(v,u)` must be equal. This is not the case for the Edge type of the triangulation. |
| `vertex_descriptor` | `unspecified_type` | Identify vertices in the graph. |
| `halfedge_descriptor` | `unspecified_type` | Identify halfedges in the graph. It is constructible from and convertible to `Triangulation::Edge`. It is not a simple typedef, but a proper class, because there is no representation for halfedges in the 2D triangulation data structure. |
| `edge_descriptor` | `unspecified_type` | Identify edges in the graph. It is constructible from and convertible to `Triangulation::Edge`. It is not a simple typedef, but a proper class, because in an undirected graph the edges `(u,v)` and `(v,u)` must be equal. This is not the case for the Edge type of the triangulation. |
| `face_descriptor` | `unspecified_type` | Identify faces in the graph. |
| `adjacency_iterator` | `unspecified_type` | An iterator to traverse through the vertices adjacent to a vertex. Its value type is `vertex_descriptor`. |
| `out_edge_iterator` | `unspecified_type` | An iterator to traverse through the outgoing edges incident to a vertex. Its value type is `edge_descriptor`. |
| `in_edge_iterator` | `unspecified_type` | An iterator to traverse through the incoming edges incident to a vertex. Its value type is `edge_descriptor`. |
| `vertex_iterator` | `unspecified_type` | An iterator to traverse through the vertices of the graph. Its value type is `vertex_descriptor`. |
| `edge_iterator` | `unspecified_type` | An iterator to traverse through the edges of the graph. Its value type is `edge_descriptor`. |
| `vertex_iterator` | `unspecified_type` | An iterator to traverse through the vertices of the graph. Its value type is `vertex_descriptor`. |
| `halfedge_iterator` | `unspecified_type` | An iterator to traverse through the halfedges of the graph. Its value type is `halfedge_descriptor`. |
| `edge_iterator` | `unspecified_type` | An iterator to traverse through the edges of the graph. Its value type is `edge_descriptor`. |
| `face_iterator` | `unspecified_type` | An iterator to traverse through the faces of the graph. Its value type is `face_descriptor`. |
| `directed_category` | `boost::undirected_tag` | This graph is not directed. |
| `edge_parallel_category` | `boost::disallow_parallel_edge_tag` | This graph does not support multiedges. |
| `traversal_category` | Inherits from `boost::bidirectional_graph_tag`, `boost::adjacency_graph_tag`, `boost::vertex_list_graph_tag`, and `boost::edge_list_graph_tag` | The ways in which the vertices in the graph can be traversed.. |

View File

@ -1,103 +1,70 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Triangulation_2.h>
#include <CGAL/boost/graph/graph_traits_Triangulation_2.h>
#include <CGAL/boost/graph/graph_traits_Triangulation_2.h>
#include <CGAL/boost/graph/dijkstra_shortest_paths.h>
#include <boost/graph/filtered_graph.hpp>
#include <fstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point;
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point;
typedef CGAL::Triangulation_2<K> Triangulation;
typedef CGAL::Triangulation_2<K> Triangulation;
// As we want to run Dijskra's shortest path algorithm we only
// consider finite vertices and edges.
typedef boost::graph_traits<Triangulation>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Triangulation>::vertex_iterator vertex_iterator;
template <typename T>
struct Is_finite {
typedef std::map<vertex_descriptor, int> VertexIndexMap;
typedef boost::associative_property_map<VertexIndexMap> VertexIdPropertyMap;
const T* t_;
Is_finite()
: t_(NULL)
{}
Is_finite(const T& t)
: t_(&t)
{ }
template <typename VertexOrEdge>
bool operator()(const VertexOrEdge& voe) const {
return ! t_->is_infinite(voe);
}
};
typedef Is_finite<Triangulation> Filter;
typedef boost::filtered_graph<Triangulation,Filter,Filter> Finite_triangulation;
typedef boost::graph_traits<Finite_triangulation>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Finite_triangulation>::vertex_iterator vertex_iterator;
typedef std::map<vertex_descriptor,int> VertexIndexMap;
VertexIndexMap vertex_id_map;
typedef boost::associative_property_map<VertexIndexMap> VertexIdPropertyMap;
VertexIdPropertyMap vertex_index_pmap(vertex_id_map);
int
main(int argc,char* argv[])
int main(int argc,char* argv[])
{
const char* filename = (argc > 1) ? argv[1] : "data/points.xy";
std::ifstream input(filename);
Triangulation t;
Filter is_finite(t);
Finite_triangulation ft(t, is_finite, is_finite);
Triangulation tr;
Point p ;
while(input >> p){
t.insert(p);
}
while(input >> p)
tr.insert(p);
vertex_iterator vit, ve;
// Associate indices to the vertices
VertexIndexMap vertex_id_map;
VertexIdPropertyMap vertex_index_pmap(vertex_id_map);
int index = 0;
// boost::tie assigns the first and second element of the std::pair
// returned by boost::vertices to the variables vit and ve
for(boost::tie(vit,ve)=boost::vertices(ft); vit!=ve; ++vit ){
vertex_descriptor vd = *vit;
vertex_id_map[vd]= index++;
}
for(vertex_descriptor vd : vertices(tr))
vertex_id_map[vd] = index++;
// Dijkstra's shortest path needs property maps for the predecessor and distance
// We first declare a vector
std::vector<vertex_descriptor> predecessor(boost::num_vertices(ft));
// and then turn it into a property map
boost::iterator_property_map<std::vector<vertex_descriptor>::iterator,
VertexIdPropertyMap>
predecessor_pmap(predecessor.begin(), vertex_index_pmap);
std::vector<vertex_descriptor> predecessor(num_vertices(tr));
std::vector<double> distance(boost::num_vertices(ft));
boost::iterator_property_map<std::vector<double>::iterator,
VertexIdPropertyMap>
// and then turn it into a property map
boost::iterator_property_map<std::vector<vertex_descriptor>::iterator, VertexIdPropertyMap>
predecessor_pmap(predecessor.begin(), vertex_index_pmap);
std::vector<double> distance(num_vertices(tr));
boost::iterator_property_map<std::vector<double>::iterator, VertexIdPropertyMap>
distance_pmap(distance.begin(), vertex_index_pmap);
// start at an arbitrary vertex
vertex_descriptor source = *boost::vertices(ft).first;
vertex_descriptor source = *vertices(tr).first;
std::cout << "\nStart dijkstra_shortest_paths at " << source->point() <<"\n";
boost::dijkstra_shortest_paths(ft, source,
distance_map(distance_pmap)
.predecessor_map(predecessor_pmap)
.vertex_index_map(vertex_index_pmap));
boost::dijkstra_shortest_paths(tr, source,
distance_map(distance_pmap)
.predecessor_map(predecessor_pmap)
.vertex_index_map(vertex_index_pmap));
for(boost::tie(vit,ve)=boost::vertices(ft); vit!=ve; ++vit ){
vertex_descriptor vd = *vit;
for(vertex_descriptor vd : vertices(tr))
{
std::cout << vd->point() << " [" << vertex_id_map[vd] << "] ";
std::cout << " has distance = " << boost::get(distance_pmap,vd)
<< " and predecessor ";
vd = boost::get(predecessor_pmap,vd);
std::cout << " has distance = " << boost::get(distance_pmap,vd)
<< " and predecessor ";
vd = boost::get(predecessor_pmap,vd);
std::cout << vd->point() << " [" << vertex_id_map[vd] << "]\n ";
}
return 0;
return EXIT_SUCCESS;
}

View File

@ -1,94 +1,66 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <CGAL/Triangulation_vertex_base_with_id_2.h>
#include <CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h>
#include <CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h>
#include <CGAL/boost/graph/dijkstra_shortest_paths.h>
#include <boost/graph/filtered_graph.hpp>
#include <fstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point;
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point;
typedef CGAL::Triangulation_vertex_base_with_id_2<K> Tvb;
typedef CGAL::Triangulation_face_base_2<K> Tfb;
typedef CGAL::Triangulation_data_structure_2<Tvb,Tfb> Tds;
typedef CGAL::Delaunay_triangulation_2<K, Tds> Triangulation;
typedef CGAL::Triangulation_vertex_base_with_id_2<K> Tvb;
typedef CGAL::Triangulation_face_base_2<K> Tfb;
typedef CGAL::Triangulation_data_structure_2<Tvb, Tfb> Tds;
typedef CGAL::Delaunay_triangulation_2<K, Tds> Triangulation;
// consider finite vertices and edges.
typedef boost::graph_traits<Triangulation>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Triangulation>::vertex_iterator vertex_iterator;
template <typename T>
struct Is_finite {
typedef boost::property_map<Triangulation, boost::vertex_index_t>::type VertexIdPropertyMap;
const T* t_;
Is_finite()
: t_(NULL)
{}
Is_finite(const T& t)
: t_(&t)
{ }
template <typename VertexOrEdge>
bool operator()(const VertexOrEdge& voe) const {
return ! t_->is_infinite(voe);
}
};
typedef Is_finite<Triangulation> Filter;
typedef boost::filtered_graph<Triangulation,Filter,Filter> Finite_triangulation;
typedef boost::graph_traits<Finite_triangulation>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Finite_triangulation>::vertex_iterator vertex_iterator;
int
main(int argc,char* argv[])
int main(int argc,char* argv[])
{
const char* filename = (argc > 1) ? argv[1] : "data/points.xy";
std::ifstream input(filename);
Triangulation t;
Filter is_finite(t);
Finite_triangulation ft(t, is_finite, is_finite);
Triangulation tr;
Point p ;
while(input >> p){
t.insert(p);
}
Point p;
while(input >> p)
tr.insert(p);
vertex_iterator vit, ve;
// associate indices to the vertices
int index = 0;
for(boost::tie(vit,ve)=boost::vertices(ft); vit!=ve; ++vit ){
vertex_descriptor vd = *vit;
for(vertex_descriptor vd : vertices(tr))
vd->id()= index++;
}
typedef boost::property_map<Triangulation, boost::vertex_index_t>::type VertexIdPropertyMap;
VertexIdPropertyMap vertex_index_pmap = get(boost::vertex_index, ft);
VertexIdPropertyMap vertex_index_pmap = get(boost::vertex_index, tr);
// Dijkstra's shortest path needs property maps for the predecessor and distance
std::vector<vertex_descriptor> predecessor(boost::num_vertices(ft));
std::vector<vertex_descriptor> predecessor(num_vertices(tr));
boost::iterator_property_map<std::vector<vertex_descriptor>::iterator, VertexIdPropertyMap>
predecessor_pmap(predecessor.begin(), vertex_index_pmap);
std::vector<double> distance(boost::num_vertices(ft));
std::vector<double> distance(num_vertices(tr));
boost::iterator_property_map<std::vector<double>::iterator, VertexIdPropertyMap>
distance_pmap(distance.begin(), vertex_index_pmap);
vertex_descriptor source = *boost::vertices(ft).first;
vertex_descriptor source = *vertices(tr).first;
std::cout << "\nStart dijkstra_shortest_paths at " << source->point() << std::endl;
boost::dijkstra_shortest_paths(ft, source ,
distance_map(distance_pmap)
.predecessor_map(predecessor_pmap));
boost::dijkstra_shortest_paths(tr, source, distance_map(distance_pmap)
.predecessor_map(predecessor_pmap));
for(boost::tie(vit,ve)=boost::vertices(ft); vit!=ve; ++vit ){
vertex_descriptor vd = *vit;
for(vertex_descriptor vd : vertices(tr))
{
std::cout << vd->point() << " [" << vd->id() << "] ";
std::cout << " has distance = " << get(distance_pmap,vd) << " and predecessor ";
vd = get(predecessor_pmap,vd);
std::cout << vd->point() << " [" << vd->id() << "]\n";
}
return 0;
return EXIT_SUCCESS;
}

View File

@ -1,98 +1,65 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h>
#include <boost/graph/kruskal_min_spanning_tree.hpp>
#include <boost/graph/filtered_graph.hpp>
#include <fstream>
#include <iostream>
#include <map>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point;
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point;
typedef CGAL::Delaunay_triangulation_2<K> Triangulation;
typedef CGAL::Delaunay_triangulation_2<K> Triangulation;
// As we only consider finite vertices and edges
// we need the following filter
template <typename T>
struct Is_finite {
const T* t_;
Is_finite()
: t_(NULL)
{}
Is_finite(const T& t)
: t_(&t)
{ }
template <typename VertexOrEdge>
bool operator()(const VertexOrEdge& voe) const {
return ! t_->is_infinite(voe);
}
};
typedef Is_finite<Triangulation> Filter;
typedef boost::filtered_graph<Triangulation,Filter,Filter> Finite_triangulation;
typedef boost::graph_traits<Finite_triangulation>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Finite_triangulation>::vertex_iterator vertex_iterator;
typedef boost::graph_traits<Finite_triangulation>::edge_descriptor edge_descriptor;
typedef boost::graph_traits<Triangulation>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Triangulation>::vertex_iterator vertex_iterator;
typedef boost::graph_traits<Triangulation>::edge_descriptor edge_descriptor;
// The BGL makes use of indices associated to the vertices
// We use a std::map to store the index
typedef std::map<vertex_descriptor,int> VertexIndexMap;
VertexIndexMap vertex_id_map;
typedef std::map<vertex_descriptor,int> VertexIndexMap;
// A std::map is not a property map, because it is not lightweight
typedef boost::associative_property_map<VertexIndexMap> VertexIdPropertyMap;
VertexIdPropertyMap vertex_index_pmap(vertex_id_map);
typedef boost::associative_property_map<VertexIndexMap> VertexIdPropertyMap;
int
main(int argc,char* argv[])
int main(int argc,char* argv[])
{
const char* filename = (argc > 1) ? argv[1] : "data/points.xy";
std::ifstream input(filename);
Triangulation t;
Filter is_finite(t);
Finite_triangulation ft(t, is_finite, is_finite);
Triangulation tr;
Point p ;
while(input >> p){
t.insert(p);
}
Point p;
while(input >> p)
tr.insert(p);
vertex_iterator vit, ve;
// Associate indices to the vertices
VertexIndexMap vertex_id_map;
VertexIdPropertyMap vertex_index_pmap(vertex_id_map);
int index = 0;
// boost::tie assigns the first and second element of the std::pair
// returned by boost::vertices to the variables vit and ve
for(boost::tie(vit,ve)=boost::vertices(ft); vit!=ve; ++vit ){
vertex_descriptor vd = *vit;
vertex_id_map[vd]= index++;
}
for(vertex_descriptor vd : vertices(tr))
vertex_id_map[vd] = index++;
// We use the default edge weight which is the squared length of the edge
// This property map is defined in graph_traits_Triangulation_2.h
// In the function call you can see a named parameter: vertex_index_map
std::list<edge_descriptor> mst;
boost::kruskal_minimum_spanning_tree(ft,
std::back_inserter(mst),
vertex_index_map(vertex_index_pmap));
std::list<edge_descriptor> mst;
boost::kruskal_minimum_spanning_tree(tr, std::back_inserter(mst),
vertex_index_map(vertex_index_pmap));
std::cout << "The edges of the Euclidean mimimum spanning tree:" << std::endl;
for(edge_descriptor ed : mst)
{
vertex_descriptor svd = source(ed, tr);
vertex_descriptor tvd = target(ed, tr);
Triangulation::Vertex_handle sv = svd;
Triangulation::Vertex_handle tv = tvd;
std::cout << "[ " << sv->point() << " | " << tv->point() << " ] " << std::endl;
}
std::cout << "The edges of the Euclidean mimimum spanning tree:" << std::endl;
for(std::list<edge_descriptor>::iterator it = mst.begin(); it != mst.end(); ++it){
edge_descriptor ed = *it;
vertex_descriptor svd = source(ed,t);
vertex_descriptor tvd = target(ed,t);
Triangulation::Vertex_handle sv = svd;
Triangulation::Vertex_handle tv = tvd;
std::cout << "[ " << sv->point() << " | " << tv->point() << " ] " << std::endl;
}
return 0;
return EXIT_SUCCESS;
}

View File

@ -1,4 +1,5 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
#include <CGAL/Triangulation_hierarchy_2.h>
@ -9,104 +10,71 @@
#include <CGAL/boost/graph/graph_traits_Triangulation_hierarchy_2.h>
#include <boost/graph/kruskal_min_spanning_tree.hpp>
#include <boost/graph/filtered_graph.hpp>
#include <fstream>
#include <iostream>
#include <map>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point;
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point;
typedef CGAL::Triangulation_vertex_base_2<K> Vbb;
typedef CGAL::Triangulation_hierarchy_vertex_base_2<Vbb> Vb;
typedef CGAL::Constrained_triangulation_face_base_2<K> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb,Fb> TDS;
typedef CGAL::Exact_predicates_tag Itag;
typedef CGAL::Constrained_Delaunay_triangulation_2<K,TDS,Itag> CDT;
typedef CGAL::Triangulation_hierarchy_2<CDT> CDTH;
typedef CGAL::Constrained_triangulation_plus_2<CDTH> Triangulation;
typedef CGAL::Triangulation_vertex_base_2<K> Vbb;
typedef CGAL::Triangulation_hierarchy_vertex_base_2<Vbb> Vb;
typedef CGAL::Constrained_triangulation_face_base_2<K> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb,Fb> TDS;
typedef CGAL::Exact_predicates_tag Itag;
typedef CGAL::Constrained_Delaunay_triangulation_2<K, TDS, Itag> CDT;
typedef CGAL::Triangulation_hierarchy_2<CDT> CDTH;
typedef CGAL::Constrained_triangulation_plus_2<CDTH> Triangulation;
// As we only consider finite vertices and edges
// we need the following filter
template <typename T>
struct Is_finite {
const T* t_;
Is_finite()
: t_(NULL)
{}
Is_finite(const T& t)
: t_(&t)
{ }
template <typename VertexOrEdge>
bool operator()(const VertexOrEdge& voe) const {
return ! t_->is_infinite(voe);
}
};
typedef Is_finite<Triangulation> Filter;
typedef boost::filtered_graph<Triangulation,Filter,Filter> Finite_triangulation;
typedef boost::graph_traits<Finite_triangulation>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Finite_triangulation>::vertex_iterator vertex_iterator;
typedef boost::graph_traits<Finite_triangulation>::edge_descriptor edge_descriptor;
typedef boost::graph_traits<Triangulation>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Triangulation>::vertex_iterator vertex_iterator;
typedef boost::graph_traits<Triangulation>::edge_descriptor edge_descriptor;
// The BGL makes use of indices associated to the vertices
// We use a std::map to store the index
typedef std::map<vertex_descriptor,int> VertexIndexMap;
VertexIndexMap vertex_id_map;
typedef std::map<vertex_descriptor,int> VertexIndexMap;
// A std::map is not a property map, because it is not lightweight
typedef boost::associative_property_map<VertexIndexMap> VertexIdPropertyMap;
VertexIdPropertyMap vertex_index_pmap(vertex_id_map);
typedef boost::associative_property_map<VertexIndexMap> VertexIdPropertyMap;
int
main(int argc,char* argv[])
int main(int argc,char* argv[])
{
const char* filename = (argc > 1) ? argv[1] : "data/points.xy";
std::ifstream input(filename);
Triangulation t;
Filter is_finite(t);
Finite_triangulation ft(t, is_finite, is_finite);
Triangulation tr;
Point p ;
while(input >> p){
t.insert(p);
}
Point p;
while(input >> p)
tr.insert(p);
vertex_iterator vit, ve;
// Associate indices to the vertices
VertexIndexMap vertex_id_map;
VertexIdPropertyMap vertex_index_pmap(vertex_id_map);
int index = 0;
// boost::tie assigns the first and second element of the std::pair
// returned by boost::vertices to the variables vit and ve
for(boost::tie(vit,ve)=boost::vertices(ft); vit!=ve; ++vit ){
vertex_descriptor vd = *vit;
vertex_id_map[vd]= index++;
}
for(vertex_descriptor vd : vertices(tr))
vertex_id_map[vd] = index++;
// We use the default edge weight which is the squared length of the edge
// This property map is defined in graph_traits_Triangulation_2.h
// In the function call you can see a named parameter: vertex_index_map
std::list<edge_descriptor> mst;
boost::kruskal_minimum_spanning_tree(ft,
std::back_inserter(mst),
vertex_index_map(vertex_index_pmap));
std::list<edge_descriptor> mst;
boost::kruskal_minimum_spanning_tree(tr,
std::back_inserter(mst),
vertex_index_map(vertex_index_pmap));
std::cout << "The edges of the Euclidean mimimum spanning tree:" << std::endl;
std::cout << "The edges of the Euclidean mimimum spanning tree:" << std::endl;
for(edge_descriptor ed : mst)
{
vertex_descriptor svd = source(ed, tr);
vertex_descriptor tvd = target(ed, tr);
Triangulation::Vertex_handle sv = svd;
Triangulation::Vertex_handle tv = tvd;
std::cout << "[ " << sv->point() << " | " << tv->point() << " ] " << std::endl;
}
for(std::list<edge_descriptor>::iterator it = mst.begin(); it != mst.end(); ++it){
edge_descriptor ed = *it;
vertex_descriptor svd = source(ed,t);
vertex_descriptor tvd = target(ed,t);
Triangulation::Vertex_handle sv = svd;
Triangulation::Vertex_handle tv = tvd;
std::cout << "[ " << sv->point() << " | " << tv->point() << " ] " << std::endl;
}
return 0;
return EXIT_SUCCESS;
}

View File

@ -1,38 +1,24 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Kernel/global_functions_2.h>
#include <CGAL/Regular_triangulation_2.h>
#include <CGAL/boost/graph/graph_traits_Regular_triangulation_2.h>
#include <CGAL/internal/boost/function_property_map.hpp>
#include <boost/graph/kruskal_min_spanning_tree.hpp>
#include <boost/graph/filtered_graph.hpp>
#include <fstream>
#include <iostream>
#include <map>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::FT FT;
typedef K::Weighted_point_2 Weighted_point;
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::FT FT;
typedef K::Weighted_point_2 Weighted_point;
typedef CGAL::Regular_triangulation_2<K> Triangulation;
typedef CGAL::Regular_triangulation_2<K> Triangulation;
// As we only consider finite vertices and edges
// we need the following filter
template <typename T>
struct Is_finite {
const T* t_;
Is_finite() : t_(NULL) { }
Is_finite(const T& t) : t_(&t) { }
template <typename VertexOrEdge>
bool operator()(const VertexOrEdge& voe) const {
return ! t_->is_infinite(voe);
}
};
typedef boost::graph_traits<Triangulation>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Triangulation>::vertex_iterator vertex_iterator;
typedef boost::graph_traits<Triangulation>::edge_descriptor edge_descriptor;
template <typename T>
struct Compute_edge_weight
@ -42,7 +28,7 @@ struct Compute_edge_weight
Compute_edge_weight(const T& t) : t_(t) { }
typedef typename boost::graph_traits<T>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<T>::edge_descriptor edge_descriptor;
typedef typename boost::graph_traits<T>::edge_descriptor edge_descriptor;
FT operator()(const edge_descriptor ed) const {
vertex_descriptor svd = source(ed, t_);
@ -53,69 +39,54 @@ struct Compute_edge_weight
}
};
typedef Is_finite<Triangulation> Filter;
typedef boost::filtered_graph<Triangulation,Filter,Filter> Finite_triangulation;
typedef boost::graph_traits<Finite_triangulation>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Finite_triangulation>::vertex_iterator vertex_iterator;
typedef boost::graph_traits<Finite_triangulation>::edge_descriptor edge_descriptor;
// The BGL makes use of indices associated to the vertices
// We use a std::map to store the index
typedef std::map<vertex_descriptor,int> VertexIndexMap;
VertexIndexMap vertex_id_map;
// A std::map is not a property map, because it is not lightweight
typedef boost::associative_property_map<VertexIndexMap> VertexIdPropertyMap;
VertexIdPropertyMap vertex_index_pmap(vertex_id_map);
int
main(int argc,char* argv[])
int main(int argc,char* argv[])
{
const char* filename = (argc > 1) ? argv[1] : "data/weighted_points.xyw";
std::ifstream input(filename);
Triangulation t;
Filter is_finite(t);
Finite_triangulation ft(t, is_finite, is_finite);
Triangulation tr;
Weighted_point wp ;
while(input >> wp){
t.insert(wp);
}
Weighted_point wp;
while(input >> wp)
tr.insert(wp);
// Note that with the input "data/weighted_points.xyw", there is one hidden vertex
std::cout << "number of hidden vertices: " << t.number_of_hidden_vertices() << std::endl;
std::cout << "number of hidden vertices: " << tr.number_of_hidden_vertices() << std::endl;
vertex_iterator vit, ve;
// Associate indices to the vertices
VertexIndexMap vertex_id_map;
VertexIdPropertyMap vertex_index_pmap(vertex_id_map);
int index = 0;
// boost::tie assigns the first and second element of the std::pair
// returned by boost::vertices to the variables vit and ve
for(boost::tie(vit,ve)=boost::vertices(ft); vit!=ve; ++vit ){
vertex_descriptor vd = *vit;
for(vertex_descriptor vd : vertices(tr))
vertex_id_map[vd]= index++;
}
// We use a custom edge length property map that computes the power distance
// between the extremities of an edge of the regular triangulation
typedef Compute_edge_weight<Triangulation> Edge_weight_functor;
// In the function call you can see a named parameter: vertex_index_map
std::list<edge_descriptor> mst;
boost::kruskal_minimum_spanning_tree(
ft, std::back_inserter(mst),
vertex_index_map(vertex_index_pmap).
weight_map(CGAL::internal::boost_::make_function_property_map<
edge_descriptor, FT, Edge_weight_functor>(Edge_weight_functor(t))));
std::list<edge_descriptor> mst;
boost::kruskal_minimum_spanning_tree(tr, std::back_inserter(mst),
vertex_index_map(vertex_index_pmap)
.weight_map(CGAL::internal::boost_::make_function_property_map<
edge_descriptor, FT, Edge_weight_functor>(Edge_weight_functor(tr))));
std::cout << "The edges of the Euclidean mimimum spanning tree:" << std::endl;
for(std::list<edge_descriptor>::iterator it = mst.begin(); it != mst.end(); ++it){
edge_descriptor ed = *it;
vertex_descriptor svd = source(ed,t);
vertex_descriptor tvd = target(ed,t);
Triangulation::Vertex_handle sv = svd;
Triangulation::Vertex_handle tv = tvd;
std::cout << "[ " << sv->point() << " | " << tv->point() << " ] " << std::endl;
}
std::cout << "The edges of the Euclidean mimimum spanning tree:" << std::endl;
for(edge_descriptor ed : mst)
{
vertex_descriptor svd = source(ed, tr);
vertex_descriptor tvd = target(ed, tr);
Triangulation::Vertex_handle sv = svd;
Triangulation::Vertex_handle tv = tvd;
std::cout << "[ " << sv->point() << " | " << tv->point() << " ] " << std::endl;
}
return 0;
return EXIT_SUCCESS;
}

View File

@ -1,4 +1,5 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Triangulation_2.h>
#include <CGAL/Projection_traits_xy_3.h>
#include <CGAL/boost/graph/graph_traits_Triangulation_2.h>
@ -6,110 +7,81 @@
#include <boost/graph/filtered_graph.hpp>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Epic;
typedef CGAL::Projection_traits_xy_3<Epic> K;
typedef K::Point_2 Point;
typedef CGAL::Exact_predicates_inexact_constructions_kernel Epic;
typedef CGAL::Projection_traits_xy_3<Epic> K;
typedef K::Point_2 Point;
typedef CGAL::Triangulation_2<K> Triangulation;
typedef CGAL::Triangulation_2<K> Triangulation;
typedef boost::graph_traits<Triangulation>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Triangulation>::vertex_iterator vertex_iterator;
typedef boost::graph_traits<Triangulation>::halfedge_descriptor halfedge_descriptor;
typedef boost::graph_traits<Triangulation>::halfedge_iterator halfedge_iterator;
typedef boost::graph_traits<Triangulation>::edge_iterator edge_iterator;
typedef boost::graph_traits<Triangulation>::edge_descriptor edge_descriptor;
typedef boost::graph_traits<Triangulation>::face_descriptor face_descriptor;
typedef boost::graph_traits<Triangulation>::face_iterator face_iterator;
typedef std::map<vertex_descriptor, int> VertexIndexMap;
typedef boost::associative_property_map<VertexIndexMap> VertexIdPropertyMap;
typedef boost::graph_traits<Triangulation>::vertex_descriptor vertex_descriptor;
typedef boost::graph_traits<Triangulation>::halfedge_descriptor halfedge_descriptor;
typedef boost::graph_traits<Triangulation>::halfedge_iterator halfedge_iterator;
typedef boost::graph_traits<Triangulation>::face_descriptor face_descriptor;
typedef boost::graph_traits<Triangulation>::vertex_iterator vertex_iterator;
typedef boost::graph_traits<Triangulation>::face_iterator face_iterator;
typedef boost::graph_traits<Triangulation>::edge_iterator edge_iterator;
typedef boost::graph_traits<Triangulation>::edge_descriptor edge_descriptor;
typedef boost::property_map<Triangulation, boost::vertex_point_t>::type Ppmap;
typedef std::map<vertex_descriptor,int> VertexIndexMap;
VertexIndexMap vertex_id_map;
typedef boost::associative_property_map<VertexIndexMap> VertexIdPropertyMap;
VertexIdPropertyMap vertex_index_pmap(vertex_id_map);
typedef std::map<halfedge_descriptor,int> HalfedgeIndexMap;
HalfedgeIndexMap halfedge_id_map;
typedef boost::associative_property_map<HalfedgeIndexMap> HalfedgeIdPropertyMap;
HalfedgeIdPropertyMap halfedge_index_pmap(halfedge_id_map);
int
main(int,char*[])
int main(int /*argc*/, char** /*argc*/)
{
Triangulation t;
Triangulation tr;
t.insert(Point(0.1,0,1));
t.insert(Point(1,0,1));
t.insert(Point(0.2,0.2, 2));
t.insert(Point(0,1,2));
t.insert(Point(0,2,3));
tr.insert(Point(0.1,0,1));
tr.insert(Point(1,0,1));
tr.insert(Point(0.2,0.2, 2));
tr.insert(Point(0,1,2));
tr.insert(Point(0,2,3));
vertex_iterator vit, ve;
// Associate indices to the vertices
VertexIndexMap vertex_id_map;
VertexIdPropertyMap vertex_index_pmap(vertex_id_map);
int index = 0;
// boost::tie assigns the first and second element of the std::pair
// returned by boost::vertices to the variables vit and ve
for(boost::tie(vit,ve) = vertices(t); vit!=ve; ++vit ){
vertex_descriptor vd = *vit;
if(! t.is_infinite(vd)){
vertex_id_map[vd]= index++;
}
}
for(vertex_descriptor vd : vertices(tr))
vertex_id_map[vd] = index++;
std::cerr << index << " vertices" << std::endl;
index = 0;
face_iterator fit,fe;
for(boost::tie(fit,fe) = faces(t); fit!= fe; ++fit){
face_descriptor fd = *fit;
halfedge_descriptor hd = halfedge(fd,t);
halfedge_descriptor n = next(hd,t);
halfedge_descriptor nn = next(n,t);
if(next(nn,t) != hd){
std::cerr << "the face is not a triangle" << std::endl;
}
++index;
}
std::cerr << index << " faces" << std::endl;
index = 0;
edge_iterator eit,ee;
for(boost::tie(eit,ee) = edges(t); eit!= ee; ++eit){
edge_descriptor ed = *eit;
vertex_descriptor vd = source(ed,t);
CGAL_USE(vd);
++index;
}
std::cerr << index << " edges" << std::endl;
index = 0;
halfedge_iterator hit,he;
for(boost::tie(hit,he) = halfedges(t); hit!= he; ++hit){
halfedge_descriptor hd = *hit;
vertex_descriptor vd = source(hd,t);
for(halfedge_descriptor hd : halfedges(tr))
{
vertex_descriptor vd = source(hd, tr);
CGAL_USE(vd);
++index;
}
std::cerr << index << " halfedges" << std::endl;
std::cerr << num_vertices(t) << " " << num_edges(t) << " " << num_halfedges(t) << " " << num_faces(t) << std::endl;
typedef boost::property_map<Triangulation, boost::vertex_point_t>::type Ppmap;
Ppmap ppmap = get(boost::vertex_point, t);
for(vertex_descriptor vd : vertices_around_target(*vertices(t).first, t)){
std::cout << ppmap[vd] << std::endl;
index = 0;
for(edge_descriptor ed : edges(tr))
{
vertex_descriptor vd = source(ed, tr);
CGAL_USE(vd);
++index;
}
std::cerr << index << " edges" << std::endl;
index = 0;
for(face_descriptor fd : faces(tr))
{
halfedge_descriptor hd = halfedge(fd, tr);
CGAL_USE(hd);
++index;
}
std::cerr << index << " faces" << std::endl;
ppmap[*(++vertices(t).first)] = Point(78,1,2);
std::cout << " changed point of vertex " << ppmap[*(++vertices(t).first)] << std::endl;
std::cerr << num_vertices(tr) << " " << num_halfedges(tr) << " " << num_edges(tr) << " " << num_faces(tr) << std::endl;
return 0;
std::cout << "vertices incident to the first vertex:" << std::endl;
Ppmap ppmap = get(boost::vertex_point, tr);
for(vertex_descriptor vd : vertices_around_target(*vertices(tr).first, tr))
std::cout << ppmap[vd] << std::endl;
ppmap[*(++vertices(tr).first)] = Point(78, 1, 2);
std::cout << "changed point of vertex " << ppmap[*(++vertices(tr).first)] << std::endl;
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,829 @@
// Copyright (c) 2014, 2017 GeometryFactory (France). All rights reserved.
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
// Author(s) : Maxime Gimeno,
// Mael Rouxel-Labbé
#ifndef CGAL_BOOST_GRAPH_GENERATORS_H
#define CGAL_BOOST_GRAPH_GENERATORS_H
#include <CGAL/boost/graph/iterator.h>
#include <CGAL/boost/graph/properties.h>
#include <CGAL/Random.h>
#include <CGAL/function_objects.h>
namespace CGAL {
namespace Euler {
// Some forward declaration to break the helpers.h > generators.h > Euler_operations.h cycle
template< typename Graph>
void fill_hole(typename boost::graph_traits<Graph>::halfedge_descriptor h,
Graph& g);
template<typename Graph , typename VertexRange >
typename boost::graph_traits<Graph>::face_descriptor add_face(const VertexRange& vr,
Graph& g);
} // namespace Euler
namespace internal {
template <class FaceGraph>
void swap_vertices(typename boost::graph_traits<FaceGraph>::vertex_descriptor& p,
typename boost::graph_traits<FaceGraph>::vertex_descriptor& q,
FaceGraph& g);
template<typename InputIterator>
typename std::iterator_traits<InputIterator>::value_type
random_entity_in_range(InputIterator first, InputIterator beyond,
CGAL::Random& rnd = get_default_random())
{
typedef typename std::iterator_traits<InputIterator>::difference_type size_type;
size_type zero = 0, ne = std::distance(first, beyond);
std::advance(first, rnd.uniform_int(zero, ne - 1));
return *first;
}
template<typename InputIterator>
typename std::iterator_traits<InputIterator>::value_type
random_entity_in_range(const CGAL::Iterator_range<InputIterator>& range,
CGAL::Random& rnd = get_default_random())
{
return random_entity_in_range(range.begin(), range.end(), rnd);
}
// \brief returns a random non-null vertex incident to the face `fd` of the polygon mesh `g`.
// \tparam Graph a model of `HalfedgeGraph`
template<typename Graph>
typename boost::graph_traits<Graph>::vertex_descriptor
random_vertex_in_face(typename boost::graph_traits<Graph>::face_descriptor fd,
const Graph& g,
CGAL::Random& rnd = get_default_random())
{
return internal::random_entity_in_range(vertices_around_face(halfedge(fd, g), g), rnd);
}
// \brief returns a random non-null halfedge incident to the face `fd` of the polygon mesh `g`.
// \tparam Graph a model of `HalfedgeGraph`
template<typename Graph>
typename boost::graph_traits<Graph>::halfedge_descriptor
random_halfedge_in_face(typename boost::graph_traits<Graph>::face_descriptor fd,
const Graph& g,
CGAL::Random& rnd = get_default_random())
{
return internal::random_entity_in_range(halfedges_around_face(halfedge(fd, g), g), rnd);
}
// \brief returns a random non-null vertex of the polygon mesh `g`.
// \tparam Graph a model of `VertexListGraph`
template<typename Graph>
typename boost::graph_traits<Graph>::vertex_descriptor
random_vertex_in_mesh(const Graph& g, CGAL::Random& rnd = get_default_random())
{
return internal::random_entity_in_range(vertices(g), rnd);
}
// \brief returns a random non-null halfedge of the polygon mesh `g`.
// \tparam Graph a model of `HalfedgeListGraph`
template<typename Graph>
typename boost::graph_traits<Graph>::halfedge_descriptor
random_halfedge_in_mesh(const Graph& g, CGAL::Random& rnd = get_default_random())
{
return internal::random_entity_in_range(halfedges(g), rnd);
}
// \brief returns a random non-null edge of the polygon mesh `g`.
// \tparam Graph a model of `EdgeListGraph`
template<typename Graph>
typename boost::graph_traits<Graph>::edge_descriptor
random_edge_in_mesh(const Graph& g, CGAL::Random& rnd = get_default_random())
{
return internal::random_entity_in_range(edges(g), rnd);
}
// \brief returns a random non-null face of the polygon mesh `g`.
// \tparam Graph a model of `FaceListGraph`
template<typename Graph>
typename boost::graph_traits<Graph>::face_descriptor
random_face_in_mesh(const Graph& g, CGAL::Random& rnd = get_default_random())
{
return internal::random_entity_in_range(faces(g), rnd);
}
} // namespace internal
/**
* \ingroup PkgBGLHelperFct
*
* \brief Creates an isolated triangle
* with its vertices initialized to `p0`, `p1` and `p2`, and adds it to the graph `g`.
*
* \returns the non-border halfedge that has the target vertex associated with `p0`.
**/
template<typename Graph, typename P>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_triangle(const P& p0, const P& p1, const P& p2, Graph& g)
{
typedef typename boost::graph_traits<Graph> Traits;
typedef typename Traits::vertex_descriptor vertex_descriptor;
typedef typename Traits::halfedge_descriptor halfedge_descriptor;
typedef typename Traits::face_descriptor face_descriptor;
typedef typename boost::property_map<Graph,vertex_point_t>::type Point_property_map;
Point_property_map ppmap = get(CGAL::vertex_point, g);
vertex_descriptor v0, v1, v2;
v0 = add_vertex(g);
v1 = add_vertex(g);
v2 = add_vertex(g);
ppmap[v0] = p0;
ppmap[v1] = p1;
ppmap[v2] = p2;
halfedge_descriptor h0 = halfedge(add_edge(g), g);
halfedge_descriptor h1 = halfedge(add_edge(g), g);
halfedge_descriptor h2 = halfedge(add_edge(g), g);
set_next(h0, h1, g);
set_next(h1, h2, g);
set_next(h2, h0, g);
set_target(h0, v1, g);
set_target(h1, v2, g);
set_target(h2, v0, g);
set_halfedge(v1, h0, g);
set_halfedge(v2, h1, g);
set_halfedge(v0, h2, g);
face_descriptor f = add_face(g);
set_face(h0, f, g);
set_face(h1, f, g);
set_face(h2, f, g);
set_halfedge(f, h0, g);
h0 = opposite(h0, g);
h1 = opposite(h1, g);
h2 = opposite(h2, g);
set_next(h0, h2, g);
set_next(h2, h1, g);
set_next(h1, h0, g);
set_target(h0, v0, g);
set_target(h1, v1, g);
set_target(h2, v2, g);
set_face(h0, boost::graph_traits<Graph>::null_face(), g);
set_face(h1, boost::graph_traits<Graph>::null_face(), g);
set_face(h2, boost::graph_traits<Graph>::null_face(), g);
return opposite(h2, g);
}
namespace internal {
template<typename Graph>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_quad(typename boost::graph_traits<Graph>::vertex_descriptor v0,
typename boost::graph_traits<Graph>::vertex_descriptor v1,
typename boost::graph_traits<Graph>::vertex_descriptor v2,
typename boost::graph_traits<Graph>::vertex_descriptor v3,
Graph& g)
{
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<Graph>::face_descriptor face_descriptor;
halfedge_descriptor h0 = halfedge(add_edge(g), g);
halfedge_descriptor h1 = halfedge(add_edge(g), g);
halfedge_descriptor h2 = halfedge(add_edge(g), g);
halfedge_descriptor h3 = halfedge(add_edge(g), g);
set_next(h0, h1, g);
set_next(h1, h2, g);
set_next(h2, h3, g);
set_next(h3, h0, g);
set_target(h0, v1, g);
set_target(h1, v2, g);
set_target(h2, v3, g);
set_target(h3, v0, g);
set_halfedge(v1, h0, g);
set_halfedge(v2, h1, g);
set_halfedge(v3, h2, g);
set_halfedge(v0, h3, g);
face_descriptor f = add_face(g);
set_face(h0, f, g);
set_face(h1, f, g);
set_face(h2, f, g);
set_face(h3, f, g);
set_halfedge(f, h0, g);
h0 = opposite(h0, g);
h1 = opposite(h1, g);
h2 = opposite(h2, g);
h3 = opposite(h3, g);
set_next(h0, h3, g);
set_next(h3, h2, g);
set_next(h2, h1, g);
set_next(h1, h0, g);
set_target(h0, v0, g);
set_target(h1, v1, g);
set_target(h2, v2, g);
set_target(h3, v3, g);
set_face(h0, boost::graph_traits<Graph>::null_face(), g);
set_face(h1, boost::graph_traits<Graph>::null_face(), g);
set_face(h2, boost::graph_traits<Graph>::null_face(), g);
set_face(h3, boost::graph_traits<Graph>::null_face(), g);
return opposite(h3, g);
}
// default Functor for make_grid
template<typename Size_type, typename Point>
struct Default_grid_maker
: public CGAL::Creator_uniform_3<Size_type, Point>
{
Point operator()(const Size_type& i, const Size_type& j) const {
return CGAL::Creator_uniform_3<Size_type, Point>::operator ()(i,j,0);
}
};
} // namespace internal
/**
* \ingroup PkgBGLHelperFct
*
* \brief Creates an isolated quad with
* its vertices initialized to `p0`, `p1`, `p2`, and `p3`, and adds it to the graph `g`.
*
* \returns the non-border halfedge that has the target vertex associated with `p0`.
**/
template<typename Graph, typename P>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_quad(const P& p0, const P& p1, const P& p2, const P& p3, Graph& g)
{
typedef typename boost::graph_traits<Graph> Traits;
typedef typename Traits::vertex_descriptor vertex_descriptor;
typedef typename boost::property_map<Graph,vertex_point_t>::type Point_property_map;
Point_property_map ppmap = get(CGAL::vertex_point, g);
vertex_descriptor v0, v1, v2, v3;
v0 = add_vertex(g);
v1 = add_vertex(g);
v2 = add_vertex(g);
v3 = add_vertex(g);
ppmap[v0] = p0;
ppmap[v1] = p1;
ppmap[v2] = p2;
ppmap[v3] = p3;
return internal::make_quad(v0, v1, v2, v3, g);
}
/**
* \ingroup PkgBGLHelperFct
* \brief Creates an isolated hexahedron
* with its vertices initialized to `p0`, `p1`, ...\ , and `p7`, and adds it to the graph `g`.
* \image html hexahedron.png
* \image latex hexahedron.png
* \returns the halfedge that has the target vertex associated with `p0`, in the face with the vertices with the points `p0`, `p1`, `p2`, and `p3`.
**/
template<typename Graph, typename P>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_hexahedron(const P& p0, const P& p1, const P& p2, const P& p3,
const P& p4, const P& p5, const P& p6, const P& p7, Graph& g)
{
typedef typename boost::graph_traits<Graph> Traits;
typedef typename Traits::halfedge_descriptor halfedge_descriptor;
typedef typename Traits::vertex_descriptor vertex_descriptor;
typedef typename boost::property_map<Graph,vertex_point_t>::type Point_property_map;
Point_property_map ppmap = get(CGAL::vertex_point, g);
vertex_descriptor v0, v1, v2, v3, v4, v5, v6, v7;
v0 = add_vertex(g);
v1 = add_vertex(g);
v2 = add_vertex(g);
v3 = add_vertex(g);
v4 = add_vertex(g);
v5 = add_vertex(g);
v6 = add_vertex(g);
v7 = add_vertex(g);
ppmap[v0] = p0;
ppmap[v1] = p1;
ppmap[v2] = p2;
ppmap[v3] = p3;
ppmap[v4] = p4;
ppmap[v5] = p5;
ppmap[v6] = p6;
ppmap[v7] = p7;
halfedge_descriptor ht = internal::make_quad(v4, v5, v6, v7, g);
halfedge_descriptor hb = prev(internal::make_quad(v0, v3, v2, v1, g), g);
for(int i=0; i <4; ++i)
{
halfedge_descriptor h = halfedge(add_edge(g), g);
set_target(h,target(hb, g), g);
set_next(h, opposite(hb, g), g);
set_next(opposite(prev(ht, g), g), h, g);
h = opposite(h, g);
set_target(h, source(prev(ht, g), g), g);
set_next(h, opposite(next(next(ht, g), g), g), g);
set_next(opposite(next(hb, g), g), h, g);
hb = next(hb, g);
ht = prev(ht, g);
}
for(int i=0; i <4; ++i)
{
Euler::fill_hole(opposite(hb, g), g);
hb = next(hb, g);
}
return next(next(hb, g), g);
}
/**
* \ingroup PkgBGLHelperFct
* \brief Creates an isolated tetrahedron
* with its vertices initialized to `p0`, `p1`, `p2`, and `p3`, and adds it to the graph `g`.
* \image html tetrahedron.png
* \image latex tetrahedron.png
* \returns the halfedge that has the target vertex associated with `p0`, in the face with the vertices with the points `p0`, `p1`, and `p2`.
**/
template<typename Graph, typename P>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_tetrahedron(const P& p0, const P& p1, const P& p2, const P& p3, Graph& g)
{
typedef typename boost::graph_traits<Graph> Traits;
typedef typename Traits::halfedge_descriptor halfedge_descriptor;
typedef typename Traits::vertex_descriptor vertex_descriptor;
typedef typename Traits::face_descriptor face_descriptor;
typedef typename boost::property_map<Graph,vertex_point_t>::type Point_property_map;
Point_property_map ppmap = get(CGAL::vertex_point, g);
vertex_descriptor v0, v1, v2, v3;
v0 = add_vertex(g);
v2 = add_vertex(g); // this and the next line are switched to keep points in order
v1 = add_vertex(g);
v3 = add_vertex(g);
ppmap[v0] = p0;
ppmap[v1] = p2;// this and the next line are switched to reorient the surface
ppmap[v2] = p1;
ppmap[v3] = p3;
halfedge_descriptor h0 = halfedge(add_edge(g), g);
halfedge_descriptor h1 = halfedge(add_edge(g), g);
halfedge_descriptor h2 = halfedge(add_edge(g), g);
set_next(h0, h1, g);
set_next(h1, h2, g);
set_next(h2, h0, g);
set_target(h0, v1, g);
set_target(h1, v2, g);
set_target(h2, v0, g);
set_halfedge(v1, h0, g);
set_halfedge(v2, h1, g);
set_halfedge(v0, h2, g);
face_descriptor f = add_face(g);
set_face(h0, f, g);
set_face(h1, f, g);
set_face(h2, f, g);
set_halfedge(f, h0, g);
h0 = opposite(h0, g);
h1 = opposite(h1, g);
h2 = opposite(h2, g);
set_next(h0, h2, g);
set_next(h2, h1, g);
set_next(h1, h0, g);
set_target(h0, v0, g);
set_target(h1, v1, g);
set_target(h2, v2, g);
halfedge_descriptor h3 = halfedge(add_edge(g), g);
halfedge_descriptor h4 = halfedge(add_edge(g), g);
halfedge_descriptor h5 = halfedge(add_edge(g), g);
set_target(h3, v3, g);
set_target(h4, v3, g);
set_target(h5, v3, g);
set_halfedge(v3, h3, g);
set_next(h0, h3, g);
set_next(h1, h4, g);
set_next(h2, h5, g);
set_next(h3, opposite(h4, g), g);
set_next(h4, opposite(h5, g), g);
set_next(h5, opposite(h3, g), g);
set_next(opposite(h4, g), h0, g);
set_next(opposite(h5, g), h1, g);
set_next(opposite(h3, g), h2, g);
set_target(opposite(h3, g), v0, g);
set_target(opposite(h4, g), v1, g);
set_target(opposite(h5, g), v2, g);
f = add_face(g);
set_halfedge(f, h0, g);
set_face(h0, f, g);
set_face(h3, f, g);
set_face(opposite(h4, g), f, g);
f = add_face(g);
set_halfedge(f, h1, g);
set_face(h1, f, g);
set_face(h4, f, g);
set_face(opposite(h5, g), f, g);
f = add_face(g);
set_halfedge(f, h2, g);
set_face(h2, f, g);
set_face(h5, f, g);
set_face(opposite(h3, g), f, g);
return opposite(h2, g);
}
/**
* \ingroup PkgBGLHelperFct
*
* \brief Creates a triangulated regular prism, outward oriented,
* having `nb_vertices` vertices in each of its bases and adds it to the graph `g`.
* If `center` is (0, 0, 0), then the first point of the prism is (`radius`, `height`, 0)
*
* \param nb_vertices the number of vertices per base. It must be greater than or equal to 3.
* \param g the graph in which the regular prism will be created.
* \param base_center the center of the circle in which the lower base is inscribed.
* \param height the distance between the two bases.
* \param radius the radius of the circles in which the bases are inscribed.
* \param is_closed determines if the bases must be created or not. If `is_closed` is `true`, `center` is a vertex.
*
* \returns the halfedge that has the target vertex associated with the first point in the first face.
*/
template<class Graph, class P>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_regular_prism(typename boost::graph_traits<Graph>::vertices_size_type nb_vertices,
Graph& g,
const P& base_center = P(0,0,0),
typename CGAL::Kernel_traits<P>::Kernel::FT height = 1.0,
typename CGAL::Kernel_traits<P>::Kernel::FT radius = 1.0,
bool is_closed = true)
{
CGAL_assertion(nb_vertices >= 3);
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typedef typename CGAL::Kernel_traits<P>::Kernel::FT FT;
typedef typename boost::property_map<Graph, vertex_point_t>::type Point_property_map;
Point_property_map vpmap = get(CGAL::vertex_point, g);
const FT to_rad = CGAL_PI / 180.0;
const FT precision = 360.0 / nb_vertices;
const FT diameter = 2 * radius;
std::vector<vertex_descriptor> vertices;
vertices.resize(nb_vertices*2);
for(typename boost::graph_traits<Graph>::vertices_size_type i=0; i<nb_vertices*2; ++i)
vertices[i] = add_vertex(g);
//fill vertices
for(typename boost::graph_traits<Graph>::vertices_size_type i=0; i < nb_vertices; ++i)
{
put(vpmap, vertices[i],
P(0.5*diameter * cos(i*precision*to_rad) + base_center.x(),
height+base_center.y(),
-0.5*diameter * sin(i*precision*to_rad) + base_center.z()));
put(vpmap,
vertices[i+nb_vertices],
P(0.5*diameter * cos(i*precision*to_rad) + base_center.x(),
base_center.y(),
-0.5*diameter * sin(i*precision*to_rad) + base_center.z()));
}
//fill faces
std::vector<vertex_descriptor> face;
face.resize(3);
for(typename boost::graph_traits<Graph>::vertices_size_type i=0; i<nb_vertices; ++i)
{
face[0] = vertices[(i+1)%(nb_vertices)];
face[1] = vertices[i];
face[2] = vertices[(i+1)%(nb_vertices) + nb_vertices];
Euler::add_face(face, g);
face[0] = vertices[(i+1)%(nb_vertices) + nb_vertices];
face[1] = vertices[i];
face[2] = vertices[i + nb_vertices];
Euler::add_face(face, g);
}
//close
if(is_closed)
{
//add the base_center of the fans
vertex_descriptor top = add_vertex(g);
vertex_descriptor bot = add_vertex(g);
put(vpmap, top, P(base_center.x(), height+base_center.y(),base_center.z()));
put(vpmap, bot, P(base_center.x(),base_center.y(),base_center.z()));
//add the faces
for(typename boost::graph_traits<Graph>::vertices_size_type i=0; i<nb_vertices; ++i)
{
face[0] = vertices[i];
face[1] = vertices[(i+1)%(nb_vertices)];
face[2] = top;
Euler::add_face(face, g);
face[0] = bot;
face[1] = vertices[(i+1)%(nb_vertices) + nb_vertices];
face[2] = vertices[i + nb_vertices];
Euler::add_face(face, g);
}
}
return halfedge(vertices[0], vertices[1], g).first;
}
/**
* \ingroup PkgBGLHelperFct
* \brief Creates a pyramid, outward oriented, having `nb_vertices` vertices in its base and adds it to the graph `g`.
*
* If `center` is `(0, 0, 0)`, then the first point of the base is `(radius, 0, 0)`
*
* \param nb_vertices the number of vertices in the base. It must be greater than or equal to 3.
* \param g the graph in which the pyramid will be created
* \param base_center the center of the circle in which the base is inscribed.
* \param height the distance between the base and the apex.
* \param radius the radius of the circle in which the base is inscribed.
* \param is_closed determines if the base must be created or not. If `is_closed` is `true`, `center` is a vertex.
*
* \returns the halfedge that has the target vertex associated with the apex point in the first face.
*/
template<class Graph, class P>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_pyramid(typename boost::graph_traits<Graph>::vertices_size_type nb_vertices,
Graph& g,
const P& base_center = P(0,0,0),
typename CGAL::Kernel_traits<P>::Kernel::FT height = 1.0,
typename CGAL::Kernel_traits<P>::Kernel::FT radius = 1.0,
bool is_closed = true)
{
CGAL_assertion(nb_vertices >= 3);
typedef typename boost::property_map<Graph,vertex_point_t>::type Point_property_map;
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typedef typename CGAL::Kernel_traits<P>::Kernel::FT FT;
const FT to_rad = CGAL_PI / 180.0;
const FT precision = 360.0/nb_vertices;
const FT diameter = 2*radius;
Point_property_map vpmap = get(CGAL::vertex_point, g);
std::vector<vertex_descriptor> vertices;
vertices.resize(nb_vertices);
for(typename boost::graph_traits<Graph>::vertices_size_type i=0; i<nb_vertices; ++i)
vertices[i] = add_vertex(g);
vertex_descriptor apex = add_vertex(g);
//fill vertices
put(vpmap, apex,
P(base_center.x(),
base_center.y() + height,
base_center.z()));
for(typename boost::graph_traits<Graph>::vertices_size_type i=0; i<nb_vertices; ++i)
{
put(vpmap, vertices[i],
P(0.5*diameter*cos(i*precision*to_rad)+base_center.x(),
base_center.y(),
-0.5*diameter*sin(i*precision*to_rad)+base_center.z()));
}
//fill faces
std::vector<vertex_descriptor> face;
face.resize(3);
for(typename boost::graph_traits<Graph>::vertices_size_type i=0; i<nb_vertices; ++i)
{
face[0] = apex;
face[1] = vertices[i];
face[2] = vertices[(i+1)%(nb_vertices)];
Euler::add_face(face, g);
}
//close
if(is_closed)
{
//add the center of the fan
vertex_descriptor bot = add_vertex(g);
put(vpmap, bot, P(base_center.x(),base_center.y(),base_center.z()));
//add the faces
for(typename boost::graph_traits<Graph>::vertices_size_type i=0; i<nb_vertices; ++i)
{
face[0] = bot;
face[1] = vertices[(i+1)%(nb_vertices)];
face[2] = vertices[i];
Euler::add_face(face, g);
}
}
return halfedge(vertices[0], apex, g).first;
}
/**
* \ingroup PkgBGLHelperFct
*
* \brief Creates an icosahedron, outward oriented, centered in `center` and adds it to the graph `g`.
*
* \param g the graph in which the icosahedron will be created.
* \param center the center of the sphere in which the icosahedron is inscribed.
* \param radius the radius of the sphere in which the icosahedron is inscribed.
*
* \returns the halfedge that has the target vertex associated with the first point in the first face.
*/
template<class Graph, class P>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_icosahedron(Graph& g,
const P& center = P(0,0,0),
typename CGAL::Kernel_traits<P>::Kernel::FT radius = 1.0)
{
typedef typename boost::property_map<Graph,vertex_point_t>::type Point_property_map;
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
Point_property_map vpmap = get(CGAL::vertex_point, g);
// create the initial icosahedron
std::vector<vertex_descriptor> v_vertices;
v_vertices.resize(12);
for(int i=0; i<12; ++i)
v_vertices[i] = add_vertex(g);
typename CGAL::Kernel_traits<P>::Kernel::FT t = radius * (1.0 + CGAL::approximate_sqrt(5.0)) / 2.0;
put(vpmap, v_vertices[0], P(-radius + center.x(), t + center.y(), 0.0 + center.z()));
put(vpmap, v_vertices[1], P( radius + center.x(), t + center.y(), 0.0 + center.z()));
put(vpmap, v_vertices[2], P(-radius + center.x(), -t + center.y(), 0.0 + center.z()));
put(vpmap, v_vertices[3], P( radius + center.x(), -t + center.y(), 0.0 + center.z()));
put(vpmap, v_vertices[4], P( 0.0 + center.x(), -radius + center.y(), t + center.z()));
put(vpmap, v_vertices[5], P( 0.0 + center.x(), radius + center.y(), t + center.z()));
put(vpmap, v_vertices[6], P( 0.0 + center.x(), -radius + center.y(), -t + center.z()));
put(vpmap, v_vertices[7], P( 0.0 + center.x(), radius + center.y(), -t + center.z()));
put(vpmap, v_vertices[8], P( t + center.x(), 0.0 + center.y(), -radius + center.z()));
put(vpmap, v_vertices[9], P( t + center.x(), 0.0 + center.y(), radius + center.z()));
put(vpmap, v_vertices[10], P(-t + center.x(), 0.0 + center.y(), -radius + center.z()));
put(vpmap, v_vertices[11], P(-t + center.x(), 0.0 + center.y(), radius + center.z()));
std::vector<vertex_descriptor> face;
face.resize(3);
face[1] = v_vertices[0]; face[0] = v_vertices[5]; face[2] = v_vertices[11];
Euler::add_face(face, g);
face[1] = v_vertices[0]; face[0] = v_vertices[1]; face[2] = v_vertices[5];
Euler::add_face(face, g);
face[1] = v_vertices[0]; face[0] = v_vertices[7]; face[2] = v_vertices[1];
Euler::add_face(face, g);
face[1] = v_vertices[0]; face[0] = v_vertices[10]; face[2] = v_vertices[7];
Euler::add_face(face, g);
face[1] = v_vertices[0]; face[0] = v_vertices[11]; face[2] = v_vertices[10];
Euler::add_face(face, g);
face[1] = v_vertices[1]; face[0] = v_vertices[9]; face[2] = v_vertices[5];
Euler::add_face(face, g);
face[1] = v_vertices[5]; face[0] = v_vertices[4]; face[2] = v_vertices[11];
Euler::add_face(face, g);
face[1] = v_vertices[11]; face[0] = v_vertices[2]; face[2] = v_vertices[10];
Euler::add_face(face, g);
face[1] = v_vertices[10]; face[0] = v_vertices[6]; face[2] = v_vertices[7];
Euler::add_face(face, g);
face[1] = v_vertices[7]; face[0] = v_vertices[8]; face[2] = v_vertices[1];
Euler::add_face(face, g);
face[1] = v_vertices[3]; face[0] = v_vertices[4]; face[2] = v_vertices[9];
Euler::add_face(face, g);
face[1] = v_vertices[3]; face[0] = v_vertices[2]; face[2] = v_vertices[4];
Euler::add_face(face, g);
face[1] = v_vertices[3]; face[0] = v_vertices[6]; face[2] = v_vertices[2];
Euler::add_face(face, g);
face[1] = v_vertices[3]; face[0] = v_vertices[8]; face[2] = v_vertices[6];
Euler::add_face(face, g);
face[1] = v_vertices[3]; face[0] = v_vertices[9]; face[2] = v_vertices[8];
Euler::add_face(face, g);
face[1] = v_vertices[4]; face[0] = v_vertices[5]; face[2] = v_vertices[9];
Euler::add_face(face, g);
face[1] = v_vertices[2]; face[0] = v_vertices[11]; face[2] = v_vertices[4];
Euler::add_face(face, g);
face[1] = v_vertices[6]; face[0] = v_vertices[10]; face[2] = v_vertices[2];
Euler::add_face(face, g);
face[1] = v_vertices[8]; face[0] = v_vertices[7]; face[2] = v_vertices[6];
Euler::add_face(face, g);
face[1] = v_vertices[9]; face[0] = v_vertices[1]; face[2] = v_vertices[8];
Euler::add_face(face, g);
return halfedge(v_vertices[1], v_vertices[0], g).first;
}
/*!
* \ingroup PkgBGLHelperFct
*
* \brief Creates a row major ordered grid with `i` cells along the width and `j` cells
* along the height and adds it to the graph `g`.
* An internal property map for `CGAL::vertex_point_t` must be available in `Graph`.
*
* \param i the number of cells along the width.
* \param j the number of cells along the height.
* \param g the graph in which the grid will be created.
* \param calculator the functor that will assign coordinates to the grid vertices.
* \param triangulated decides if a cell is composed of one quad or two triangles.
* If `triangulated` is `true`, the diagonal of each cell is oriented from (0,0) to (1,1)
* in the cell coordinates.
*
*\tparam CoordinateFunctor a function object providing `Point_3 operator()(size_type I, size_type J)` with `Point_3` being
* the value_type of the internal property_map for `CGAL::vertex_point_t`.
* and outputs a `boost::property_traits<boost::property_map<Graph,CGAL::vertex_point_t>::%type>::%value_type`.
* It will be called with arguments (`w`, `h`), with `w` in [0..`i`] and `h` in [0..`j`].
* <p>%Default: a point with positive integer coordinates (`w`, `h`, 0), with `w` in [0..`i`] and `h` in [0..`j`]
*
* \returns the non-border non-diagonal halfedge that has the target vertex associated with the first point of the grid (default is (0,0,0) ).
*/
template<class Graph, class CoordinateFunctor>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_grid(typename boost::graph_traits<Graph>::vertices_size_type i,
typename boost::graph_traits<Graph>::vertices_size_type j,
Graph& g,
const CoordinateFunctor& calculator,
bool triangulated = false)
{
typedef typename boost::property_map<Graph,vertex_point_t>::type Point_property_map;
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typename boost::graph_traits<Graph>::vertices_size_type w(i+1), h(j+1);
Point_property_map vpmap = get(CGAL::vertex_point, g);
//create the vertices
std::vector<vertex_descriptor> v_vertices;
v_vertices.resize(static_cast<std::size_t>(w*h));
for(std::size_t k = 0; k < v_vertices.size(); ++k)
v_vertices[k] = add_vertex(g);
//assign the coordinates
for(typename boost::graph_traits<Graph>::vertices_size_type a=0; a<w; ++a)
for(typename boost::graph_traits<Graph>::vertices_size_type b=0; b<h; ++b)
put(vpmap, v_vertices[a+w*b], calculator(a,b));
//create the faces
std::vector<vertex_descriptor> face;
if(triangulated)
face.resize(3);
else
face.resize(4);
for(typename boost::graph_traits<Graph>::vertices_size_type a = 0; a<w-1; ++a)
{
for(typename boost::graph_traits<Graph>::vertices_size_type b = 0; b<h-1; ++b)
{
if(triangulated)
{
face[0] = v_vertices[w*b+a];
face[1] = v_vertices[w*b+a+1];
face[2] = v_vertices[w*(b+1)+a];
Euler::add_face(face, g);
face[0] = v_vertices[w*b+a+1];
face[1] = v_vertices[w*(b+1)+a+1];
face[2] = v_vertices[w*(b+1)+a];
Euler::add_face(face, g);
}
else
{
face[0] = v_vertices[w*b+ a];
face[1] = v_vertices[w*b+ a+1];
face[2] = v_vertices[w*(b+1)+ a+1];
face[3] = v_vertices[w*(b+1)+ a];
Euler::add_face(face, g);
}
}
}
return halfedge(v_vertices[1], v_vertices[0], g).first;
}
template<class Graph>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_grid(typename boost::graph_traits<Graph>::vertices_size_type w,
typename boost::graph_traits<Graph>::vertices_size_type h,
Graph& g,
bool triangulated = false)
{
typedef typename boost::graph_traits<Graph>::vertices_size_type Size_type;
typedef typename boost::property_traits<typename boost::property_map<Graph, vertex_point_t>::type>::value_type Point;
return make_grid(w, h, g, internal::Default_grid_maker<Size_type, Point>(), triangulated);
}
} // namespace CGAL
// Here at the bottom because helpers.h must include generators (for backward compatibility reasons),
// and Euler_operations.h needs helpers.h
#include <CGAL/boost/graph/Euler_operations.h>
#endif // CGAL_BOOST_GRAPH_GENERATORS_H

View File

@ -21,29 +21,16 @@
#ifndef CGAL_BOOST_GRAPH_HELPERS_H
#define CGAL_BOOST_GRAPH_HELPERS_H
#include <boost/range/empty.hpp>
#include <CGAL/boost/graph/iterator.h>
#include <CGAL/boost/graph/properties.h>
#include <CGAL/boost/graph/internal/Has_member_clear.h>
#include <CGAL/function_objects.h>
#include <boost/unordered_set.hpp>
#include <CGAL/IO/Verbose_ostream.h>
#include <boost/range/empty.hpp>
namespace CGAL {
namespace Euler {
template< typename Graph>
void fill_hole(typename boost::graph_traits<Graph>::halfedge_descriptor h,
Graph& g);
template<typename Graph , typename VertexRange >
typename boost::graph_traits<Graph>::face_descriptor add_face(const VertexRange& vr,
Graph& g);
}//Euler
/*!
\ingroup PkgBGLHelperFct
returns `true` if the halfedge `hd` is on a border.
@ -730,674 +717,6 @@ bool is_hexahedron( typename boost::graph_traits<FaceGraph>::halfedge_descriptor
return true;
}
/**
* \ingroup PkgBGLHelperFct
* \brief Creates an isolated triangle
* with its vertices initialized to `p0`, `p1` and `p2`, and adds it to the graph `g`.
* \returns the non-border halfedge that has the target vertex associated with `p0`.
**/
template<typename Graph, typename P>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_triangle(const P& p0, const P& p1, const P& p2, Graph& g)
{
typedef typename boost::graph_traits<Graph> Traits;
typedef typename Traits::halfedge_descriptor halfedge_descriptor;
typedef typename Traits::vertex_descriptor vertex_descriptor;
typedef typename Traits::face_descriptor face_descriptor;
typedef typename boost::property_map<Graph,vertex_point_t>::type Point_property_map;
Point_property_map ppmap = get(CGAL::vertex_point, g);
vertex_descriptor v0, v1, v2;
v0 = add_vertex(g);
v1 = add_vertex(g);
v2 = add_vertex(g);
ppmap[v0] = p0;
ppmap[v1] = p1;
ppmap[v2] = p2;
halfedge_descriptor h0 = halfedge(add_edge(g),g);
halfedge_descriptor h1 = halfedge(add_edge(g),g);
halfedge_descriptor h2 = halfedge(add_edge(g),g);
set_next(h0, h1, g);
set_next(h1, h2, g);
set_next(h2, h0, g);
set_target(h0, v1, g);
set_target(h1, v2, g);
set_target(h2, v0, g);
set_halfedge(v1, h0, g);
set_halfedge(v2, h1, g);
set_halfedge(v0, h2, g);
face_descriptor f = add_face(g);
set_face(h0,f,g);
set_face(h1,f,g);
set_face(h2,f,g);
set_halfedge(f,h0,g);
h0 = opposite(h0,g);
h1 = opposite(h1,g);
h2 = opposite(h2,g);
set_next(h0, h2, g);
set_next(h2, h1, g);
set_next(h1, h0, g);
set_target(h0, v0, g);
set_target(h1, v1, g);
set_target(h2, v2, g);
set_face(h0, boost::graph_traits<Graph>::null_face(),g);
set_face(h1, boost::graph_traits<Graph>::null_face(),g);
set_face(h2, boost::graph_traits<Graph>::null_face(),g);
return opposite(h2,g);
}
namespace internal {
template<typename Graph>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_quad(typename boost::graph_traits<Graph>::vertex_descriptor v0,
typename boost::graph_traits<Graph>::vertex_descriptor v1,
typename boost::graph_traits<Graph>::vertex_descriptor v2,
typename boost::graph_traits<Graph>::vertex_descriptor v3, Graph& g)
{
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<Graph>::face_descriptor face_descriptor;
halfedge_descriptor h0 = halfedge(add_edge(g),g);
halfedge_descriptor h1 = halfedge(add_edge(g),g);
halfedge_descriptor h2 = halfedge(add_edge(g),g);
halfedge_descriptor h3 = halfedge(add_edge(g),g);
set_next(h0, h1, g);
set_next(h1, h2, g);
set_next(h2, h3, g);
set_next(h3, h0, g);
set_target(h0, v1, g);
set_target(h1, v2, g);
set_target(h2, v3, g);
set_target(h3, v0, g);
set_halfedge(v1, h0, g);
set_halfedge(v2, h1, g);
set_halfedge(v3, h2, g);
set_halfedge(v0, h3, g);
face_descriptor f = add_face(g);
set_face(h0,f,g);
set_face(h1,f,g);
set_face(h2,f,g);
set_face(h3,f,g);
set_halfedge(f,h0,g);
h0 = opposite(h0,g);
h1 = opposite(h1,g);
h2 = opposite(h2,g);
h3 = opposite(h3,g);
set_next(h0, h3, g);
set_next(h3, h2, g);
set_next(h2, h1, g);
set_next(h1, h0, g);
set_target(h0, v0, g);
set_target(h1, v1, g);
set_target(h2, v2, g);
set_target(h3, v3, g);
set_face(h0, boost::graph_traits<Graph>::null_face(),g);
set_face(h1, boost::graph_traits<Graph>::null_face(),g);
set_face(h2, boost::graph_traits<Graph>::null_face(),g);
set_face(h3, boost::graph_traits<Graph>::null_face(),g);
return opposite(h3,g);
}
//default Functor for make_grid
template<typename Size_type, typename Point>
struct Default_grid_maker
: public CGAL::Creator_uniform_3<Size_type, Point>
{
Point operator()(const Size_type& i, const Size_type& j)const
{
return CGAL::Creator_uniform_3<Size_type, Point>::operator ()(i,j,0);
}
};
} // namespace internal
/**
* \ingroup PkgBGLHelperFct
* \brief Creates an isolated quad with
* its vertices initialized to `p0`, `p1`, `p2`, and `p3`, and adds it to the graph `g`.
* \returns the non-border halfedge that has the target vertex associated with `p0`.
**/
template<typename Graph, typename P>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_quad(const P& p0, const P& p1, const P& p2, const P& p3, Graph& g)
{
typedef typename boost::graph_traits<Graph> Traits;
typedef typename Traits::vertex_descriptor vertex_descriptor;
typedef typename boost::property_map<Graph,vertex_point_t>::type Point_property_map;
Point_property_map ppmap = get(CGAL::vertex_point, g);
vertex_descriptor v0, v1, v2, v3;
v0 = add_vertex(g);
v1 = add_vertex(g);
v2 = add_vertex(g);
v3 = add_vertex(g);
ppmap[v0] = p0;
ppmap[v1] = p1;
ppmap[v2] = p2;
ppmap[v3] = p3;
return internal::make_quad(v0, v1, v2, v3, g);
}
/**
* \ingroup PkgBGLHelperFct
* \brief Creates an isolated hexahedron
* with its vertices initialized to `p0`, `p1`, ...\ , and `p7`, and adds it to the graph `g`.
* \image html hexahedron.png
* \image latex hexahedron.png
* \returns the halfedge that has the target vertex associated with `p0`, in the face with the vertices with the points `p0`, `p1`, `p2`, and `p3`.
**/
template<typename Graph, typename P>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_hexahedron(const P& p0, const P& p1, const P& p2, const P& p3,
const P& p4, const P& p5, const P& p6, const P& p7, Graph& g)
{
typedef typename boost::graph_traits<Graph> Traits;
typedef typename Traits::halfedge_descriptor halfedge_descriptor;
typedef typename Traits::vertex_descriptor vertex_descriptor;
typedef typename boost::property_map<Graph,vertex_point_t>::type Point_property_map;
Point_property_map ppmap = get(CGAL::vertex_point, g);
vertex_descriptor v0, v1, v2, v3, v4, v5, v6, v7;
v0 = add_vertex(g);
v1 = add_vertex(g);
v2 = add_vertex(g);
v3 = add_vertex(g);
v4 = add_vertex(g);
v5 = add_vertex(g);
v6 = add_vertex(g);
v7 = add_vertex(g);
ppmap[v0] = p0;
ppmap[v1] = p1;
ppmap[v2] = p2;
ppmap[v3] = p3;
ppmap[v4] = p4;
ppmap[v5] = p5;
ppmap[v6] = p6;
ppmap[v7] = p7;
halfedge_descriptor ht = internal::make_quad(v4, v5, v6, v7, g);
halfedge_descriptor hb = prev(internal::make_quad(v0, v3, v2, v1, g),g);
for(int i=0; i <4; i++){
halfedge_descriptor h = halfedge(add_edge(g),g);
set_target(h,target(hb,g),g);
set_next(h,opposite(hb,g),g);
set_next(opposite(prev(ht,g),g),h,g);
h = opposite(h,g);
set_target(h,source(prev(ht,g),g),g);
set_next(h,opposite(next(next(ht,g),g),g),g);
set_next(opposite(next(hb,g),g),h,g);
hb = next(hb,g);
ht = prev(ht,g);
}
for(int i=0; i <4; i++){
Euler::fill_hole(opposite(hb,g),g);
hb = next(hb,g);
}
return next(next(hb,g),g);
}
/**
* \ingroup PkgBGLHelperFct
* \brief Creates an isolated tetrahedron
* with its vertices initialized to `p0`, `p1`, `p2`, and `p3`, and adds it to the graph `g`.
* \image html tetrahedron.png
* \image latex tetrahedron.png
* \returns the halfedge that has the target vertex associated with `p0`, in the face with the vertices with the points `p0`, `p1`, and `p2`.
**/
template<typename Graph, typename P>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_tetrahedron(const P& p0, const P& p1, const P& p2, const P& p3, Graph& g)
{
typedef typename boost::graph_traits<Graph> Traits;
typedef typename Traits::halfedge_descriptor halfedge_descriptor;
typedef typename Traits::vertex_descriptor vertex_descriptor;
typedef typename Traits::face_descriptor face_descriptor;
typedef typename boost::property_map<Graph,vertex_point_t>::type Point_property_map;
Point_property_map ppmap = get(CGAL::vertex_point, g);
vertex_descriptor v0, v1, v2, v3;
v0 = add_vertex(g);
v2 = add_vertex(g); // this and the next line are switched to keep points in order
v1 = add_vertex(g);
v3 = add_vertex(g);
ppmap[v0] = p0;
ppmap[v1] = p2;// this and the next line are switched to reorient the surface
ppmap[v2] = p1;
ppmap[v3] = p3;
halfedge_descriptor h0 = halfedge(add_edge(g),g);
halfedge_descriptor h1 = halfedge(add_edge(g),g);
halfedge_descriptor h2 = halfedge(add_edge(g),g);
set_next(h0, h1, g);
set_next(h1, h2, g);
set_next(h2, h0, g);
set_target(h0, v1, g);
set_target(h1, v2, g);
set_target(h2, v0, g);
set_halfedge(v1, h0, g);
set_halfedge(v2, h1, g);
set_halfedge(v0, h2, g);
face_descriptor f = add_face(g);
set_face(h0,f,g);
set_face(h1,f,g);
set_face(h2,f,g);
set_halfedge(f,h0,g);
h0 = opposite(h0,g);
h1 = opposite(h1,g);
h2 = opposite(h2,g);
set_next(h0, h2, g);
set_next(h2, h1, g);
set_next(h1, h0, g);
set_target(h0, v0, g);
set_target(h1, v1, g);
set_target(h2, v2, g);
halfedge_descriptor h3 = halfedge(add_edge(g),g);
halfedge_descriptor h4 = halfedge(add_edge(g),g);
halfedge_descriptor h5 = halfedge(add_edge(g),g);
set_target(h3, v3, g);
set_target(h4, v3, g);
set_target(h5, v3, g);
set_halfedge(v3, h3, g);
set_next(h0, h3, g);
set_next(h1, h4, g);
set_next(h2, h5, g);
set_next(h3, opposite(h4,g), g);
set_next(h4, opposite(h5,g), g);
set_next(h5, opposite(h3,g), g);
set_next(opposite(h4,g), h0, g);
set_next(opposite(h5,g), h1, g);
set_next(opposite(h3,g), h2, g);
set_target(opposite(h3,g), v0, g);
set_target(opposite(h4,g), v1, g);
set_target(opposite(h5,g), v2, g);
f = add_face(g);
set_halfedge(f,h0,g);
set_face(h0, f, g);
set_face(h3, f, g);
set_face(opposite(h4,g), f, g);
f = add_face(g);
set_halfedge(f,h1,g);
set_face(h1, f, g);
set_face(h4, f, g);
set_face(opposite(h5,g), f, g);
f = add_face(g);
set_halfedge(f,h2,g);
set_face(h2, f, g);
set_face(h5, f, g);
set_face(opposite(h3,g), f, g);
return opposite(h2,g);
}
/**
* \ingroup PkgBGLHelperFct
* \brief Creates a triangulated regular prism, outward oriented,
* having `nb_vertices` vertices in each of its bases and adds it to the graph `g`.
* If `center` is (0, 0, 0), then the first point of the prism is (`radius`, `height`, 0)
* \param nb_vertices the number of vertices per base. It must be greater than or equal to 3.
* \param g the graph in which the regular prism will be created.
* \param base_center the center of the circle in which the lower base is inscribed.
* \param height the distance between the two bases.
* \param radius the radius of the circles in which the bases are inscribed.
* \param is_closed determines if the bases must be created or not. If `is_closed` is `true`, `center` is a vertex.
* \returns the halfedge that has the target vertex associated with the first point in the first face.
*/
template<class Graph, class P>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_regular_prism(
typename boost::graph_traits<Graph>::vertices_size_type nb_vertices,
Graph& g,
const P& base_center = P(0,0,0),
typename CGAL::Kernel_traits<P>::Kernel::FT height = 1.0,
typename CGAL::Kernel_traits<P>::Kernel::FT radius = 1.0,
bool is_closed = true)
{
CGAL_assertion(nb_vertices >= 3);
typedef typename boost::property_map<Graph,vertex_point_t>::type Point_property_map;
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typedef typename CGAL::Kernel_traits<P>::Kernel::FT FT;
const FT to_rad = CGAL_PI / 180.0;
const FT precision = 360.0/nb_vertices;
const FT diameter = 2*radius;
Point_property_map vpmap = get(CGAL::vertex_point, g);
std::vector<vertex_descriptor> vertices;
vertices.resize(nb_vertices*2);
for(typename boost::graph_traits<Graph>::vertices_size_type i=0; i<nb_vertices*2; ++i)
vertices[i] = add_vertex(g);
//fill vertices
for(typename boost::graph_traits<Graph>::vertices_size_type i=0; i < nb_vertices; ++i)
{
put(vpmap,
vertices[i],
P(0.5*diameter*cos(i*precision*to_rad)+base_center.x(),
height+base_center.y(),
-0.5*diameter*sin(i*precision*to_rad) + base_center.z()));
put(vpmap,
vertices[i+nb_vertices],
P(0.5*diameter*cos(i*precision*to_rad)+base_center.x(),
base_center.y(),
-0.5*diameter*sin(i*precision*to_rad)+base_center.z()));
}
std::vector<vertex_descriptor> face;
face.resize(3);
//fill faces
for(typename boost::graph_traits<Graph>::vertices_size_type i=0; i<nb_vertices; ++i)
{
face[0] = vertices[(i+1)%(nb_vertices)];
face[1] = vertices[i];
face[2] = vertices[(i+1)%(nb_vertices) + nb_vertices];
Euler::add_face(face, g);
face[0] = vertices[(i+1)%(nb_vertices) + nb_vertices];
face[1] = vertices[i];
face[2] = vertices[i + nb_vertices];
Euler::add_face(face, g);
}
//close
if(is_closed)
{
//add the base_center of the fans
vertex_descriptor top = add_vertex(g);
vertex_descriptor bot = add_vertex(g);
put(vpmap, top, P(base_center.x(),height+base_center.y(),base_center.z()));
put(vpmap, bot, P(base_center.x(),base_center.y(),base_center.z()));
//add the faces
for(typename boost::graph_traits<Graph>::vertices_size_type i=0; i<nb_vertices; ++i)
{
face[0] = vertices[i];
face[1] = vertices[(i+1)%(nb_vertices)];
face[2] = top;
Euler::add_face(face, g);
face[0] = bot;
face[1] = vertices[(i+1)%(nb_vertices) + nb_vertices];
face[2] = vertices[i + nb_vertices];
Euler::add_face(face, g);
}
}
return halfedge(vertices[0], vertices[1], g).first;
}
/**
* \ingroup PkgBGLHelperFct
* \brief Creates a pyramid, outward oriented, having `nb_vertices` vertices in its base and adds it to the graph `g`.
*
* If `center` is `(0, 0, 0)`, then the first point of the base is `(radius, 0, 0)`
* \param nb_vertices the number of vertices in the base. It must be greater than or equal to 3.
* \param g the graph in which the pyramid will be created
* \param base_center the center of the circle in which the base is inscribed.
* \param height the distance between the base and the apex.
* \param radius the radius of the circle in which the base is inscribed.
* \param is_closed determines if the base must be created or not. If `is_closed` is `true`, `center` is a vertex.
* \returns the halfedge that has the target vertex associated with the apex point in the first face.
*/
template<class Graph, class P>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_pyramid(
typename boost::graph_traits<Graph>::vertices_size_type nb_vertices,
Graph& g,
const P& base_center = P(0,0,0),
typename CGAL::Kernel_traits<P>::Kernel::FT height = 1.0,
typename CGAL::Kernel_traits<P>::Kernel::FT radius = 1.0,
bool is_closed = true)
{
CGAL_assertion(nb_vertices >= 3);
typedef typename boost::property_map<Graph,vertex_point_t>::type Point_property_map;
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typedef typename CGAL::Kernel_traits<P>::Kernel::FT FT;
const FT to_rad = CGAL_PI / 180.0;
const FT precision = 360.0/nb_vertices;
const FT diameter = 2*radius;
Point_property_map vpmap = get(CGAL::vertex_point, g);
std::vector<vertex_descriptor> vertices;
vertices.resize(nb_vertices);
for(typename boost::graph_traits<Graph>::vertices_size_type i=0;
i<nb_vertices; ++i)
vertices[i] = add_vertex(g);
vertex_descriptor apex = add_vertex(g);
//fill vertices
put(vpmap,
apex,
P(base_center.x(),
base_center.y() + height,
base_center.z()));
for(typename boost::graph_traits<Graph>::vertices_size_type i=0;
i < nb_vertices; ++i)
{
put(vpmap,
vertices[i],
P(0.5*diameter*cos(i*precision*to_rad)+base_center.x(),
base_center.y(),
-0.5*diameter*sin(i*precision*to_rad)+base_center.z()));
}
std::vector<vertex_descriptor> face;
face.resize(3);
//fill faces
for(typename boost::graph_traits<Graph>::vertices_size_type i=0;
i<nb_vertices; ++i)
{
face[0] = apex;
face[1] = vertices[i];
face[2] = vertices[(i+1)%(nb_vertices)];
Euler::add_face(face, g);
}
//close
if(is_closed)
{
//add the center of the fan
vertex_descriptor bot = add_vertex(g);
put(vpmap, bot, P(base_center.x(),base_center.y(),base_center.z()));
//add the faces
for(typename boost::graph_traits<Graph>::vertices_size_type i=0;
i<nb_vertices; ++i)
{
face[0] = bot;
face[1] = vertices[(i+1)%(nb_vertices)];
face[2] = vertices[i];
Euler::add_face(face, g);
}
}
return halfedge(vertices[0], apex, g).first;
}
/**
* \ingroup PkgBGLHelperFct
* \brief Creates an icosahedron, outward oriented, centered in `center` and adds it to the graph `g`.
* \param g the graph in which the icosahedron will be created.
* \param center the center of the sphere in which the icosahedron is inscribed.
* \param radius the radius of the sphere in which the icosahedron is inscribed.
* \returns the halfedge that has the target vertex associated with the first point in the first face.
*/
template<class Graph, class P>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_icosahedron(
Graph& g,
const P& center = P(0,0,0),
typename CGAL::Kernel_traits<P>::Kernel::FT radius = 1.0)
{
typedef typename boost::property_map<Graph,vertex_point_t>::type Point_property_map;
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
Point_property_map vpmap = get(CGAL::vertex_point, g);
// create the initial icosahedron
std::vector<vertex_descriptor> v_vertices;
v_vertices.resize(12);
for(int i=0; i<12; ++i)
v_vertices[i] = add_vertex(g);
typename CGAL::Kernel_traits<P>::Kernel::FT t =
(radius + radius*CGAL::approximate_sqrt(5.0)) / 2.0;
put(vpmap, v_vertices[0],P(-radius + center.x(), t + center.y(), 0.0 + center.z()));
put(vpmap, v_vertices[1],P( radius + center.x(), t + center.y(), 0.0 + center.z()));
put(vpmap, v_vertices[2],P(-radius + center.x(), -t + center.y(), 0.0 + center.z()));
put(vpmap, v_vertices[3],P( radius + center.x(), -t + center.y(), 0.0 + center.z()));
put(vpmap, v_vertices[4],P( 0.0 + center.x(), -radius + center.y(), t + center.z()));
put(vpmap, v_vertices[5],P( 0.0 + center.x(), radius + center.y(), t + center.z()));
put(vpmap, v_vertices[6],P( 0.0 + center.x(), -radius + center.y(), -t + center.z()));
put(vpmap, v_vertices[7],P( 0.0 + center.x(), radius + center.y(), -t + center.z()));
put(vpmap, v_vertices[8],P( t + center.x(), 0.0 + center.y(), -radius + center.z()));
put(vpmap, v_vertices[9],P( t + center.x(), 0.0 + center.y(), radius + center.z()));
put(vpmap, v_vertices[10],P(-t + center.x(), 0.0 + center.y(), -radius + center.z()));
put(vpmap, v_vertices[11],P(-t + center.x(), 0.0 + center.y(), radius + center.z()));
std::vector<vertex_descriptor> face;
face.resize(3);
face[1] = v_vertices[0]; face[0] = v_vertices[5]; face[2] = v_vertices[11];
Euler::add_face(face, g);
face[1] = v_vertices[0]; face[0] = v_vertices[1]; face[2] = v_vertices[5];
Euler::add_face(face, g);
face[1] = v_vertices[0]; face[0] = v_vertices[7]; face[2] = v_vertices[1];
Euler::add_face(face, g);
face[1] = v_vertices[0]; face[0] = v_vertices[10]; face[2] = v_vertices[7];
Euler::add_face(face, g);
face[1] = v_vertices[0]; face[0] = v_vertices[11]; face[2] = v_vertices[10];
Euler::add_face(face, g);
face[1] = v_vertices[1] ; face[0] = v_vertices[9] ; face[2] = v_vertices[5];
Euler::add_face(face, g);
face[1] = v_vertices[5] ; face[0] = v_vertices[4]; face[2] = v_vertices[11];
Euler::add_face(face, g);
face[1] = v_vertices[11]; face[0] = v_vertices[2]; face[2] = v_vertices[10];
Euler::add_face(face, g);
face[1] = v_vertices[10]; face[0] = v_vertices[6] ; face[2] = v_vertices[7];
Euler::add_face(face, g);
face[1] = v_vertices[7] ; face[0] = v_vertices[8] ; face[2] = v_vertices[1];
Euler::add_face(face, g);
face[1] = v_vertices[3] ; face[0] = v_vertices[4] ; face[2] = v_vertices[9];
Euler::add_face(face, g);
face[1] = v_vertices[3] ; face[0] = v_vertices[2] ; face[2] = v_vertices[4];
Euler::add_face(face, g);
face[1] = v_vertices[3] ; face[0] = v_vertices[6] ; face[2] = v_vertices[2];
Euler::add_face(face, g);
face[1] = v_vertices[3] ; face[0] = v_vertices[8] ; face[2] = v_vertices[6];
Euler::add_face(face, g);
face[1] = v_vertices[3] ; face[0] = v_vertices[9] ; face[2] = v_vertices[8];
Euler::add_face(face, g);
face[1] = v_vertices[4] ; face[0] = v_vertices[5] ; face[2] = v_vertices[9] ;
Euler::add_face(face, g);
face[1] = v_vertices[2] ; face[0] = v_vertices[11] ; face[2] = v_vertices[4];
Euler::add_face(face, g);
face[1] = v_vertices[6] ; face[0] = v_vertices[10] ; face[2] = v_vertices[2];
Euler::add_face(face, g);
face[1] = v_vertices[8] ; face[0] = v_vertices[7] ; face[2] = v_vertices[6] ;
Euler::add_face(face, g);
face[1] = v_vertices[9] ; face[0] = v_vertices[1] ; face[2] = v_vertices[8] ;
Euler::add_face(face, g);
return halfedge(v_vertices[1], v_vertices[0], g).first;
}
/*!
* \ingroup PkgBGLHelperFct
*
* \brief Creates a row major ordered grid with `i` cells along the width and `j` cells
* along the height and adds it to the graph `g`.
* An internal property map for `CGAL::vertex_point_t` must be available in `Graph`.
*
* \param i the number of cells along the width.
* \param j the number of cells along the height.
* \param g the graph in which the grid will be created.
* \param calculator the functor that will assign coordinates to the grid vertices.
* \param triangulated decides if a cell is composed of one quad or two triangles.
* If `triangulated` is `true`, the diagonal of each cell is oriented from (0,0) to (1,1)
* in the cell coordinates.
*\tparam CoordinateFunctor a function object providing `Point_3 operator()(size_type I, size_type J)` with `Point_3` being
* the value_type of the internal property_map for `CGAL::vertex_point_t`.
* and outputs a `boost::property_traits<boost::property_map<Graph,CGAL::vertex_point_t>::%type>::%value_type`.
* It will be called with arguments (`w`, `h`), with `w` in [0..`i`] and `h` in [0..`j`].
* <p>%Default: a point with positive integer coordinates (`w`, `h`, 0), with `w` in [0..`i`] and `h` in [0..`j`]
* \returns the non-border non-diagonal halfedge that has the target vertex associated with the first point of the grid (default is (0,0,0) ).
*/
template<class Graph, class CoordinateFunctor>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_grid(typename boost::graph_traits<Graph>::vertices_size_type i,
typename boost::graph_traits<Graph>::vertices_size_type j,
Graph& g,
const CoordinateFunctor& calculator,
bool triangulated = false)
{
typedef typename boost::property_map<Graph,vertex_point_t>::type Point_property_map;
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typename boost::graph_traits<Graph>::vertices_size_type w(i+1), h(j+1);
Point_property_map vpmap = get(CGAL::vertex_point, g);
//create the vertices
std::vector<vertex_descriptor> v_vertices;
v_vertices.resize(static_cast<std::size_t>(w*h));
for(std::size_t k = 0; k < v_vertices.size(); ++k)
v_vertices[k] = add_vertex(g);
//assign the coordinates
for(typename boost::graph_traits<Graph>::vertices_size_type a = 0; a<w; ++a)
{
for(typename boost::graph_traits<Graph>::vertices_size_type b=0; b<h; ++b)
{
put(vpmap, v_vertices[a+w*b], calculator(a,b));
}
}
//create the faces
std::vector<vertex_descriptor> face;
if(triangulated)
face.resize(3);
else
face.resize(4);
for(typename boost::graph_traits<Graph>::vertices_size_type a = 0; a<w-1; ++a)
{
for(typename boost::graph_traits<Graph>::vertices_size_type b = 0; b<h-1; ++b)
{
if(triangulated)
{
face[0] = v_vertices[w*b+a];
face[1] = v_vertices[w*b+a+1];
face[2] = v_vertices[w*(b+1)+a];
Euler::add_face(face, g);
face[0] = v_vertices[w*b+a+1];
face[1] = v_vertices[w*(b+1)+a+1];
face[2] = v_vertices[w*(b+1)+a];
Euler::add_face(face, g);
}
else
{
face[0] = v_vertices[w*b+ a];
face[1] = v_vertices[w*b+ a+1];
face[2] = v_vertices[w*(b+1)+ a+1];
face[3] = v_vertices[w*(b+1)+ a];
Euler::add_face(face, g);
}
}
}
return halfedge(v_vertices[1], v_vertices[0], g).first;
}
template<class Graph>
typename boost::graph_traits<Graph>::halfedge_descriptor
make_grid(typename boost::graph_traits<Graph>::vertices_size_type w,
typename boost::graph_traits<Graph>::vertices_size_type h,
Graph& g,
bool triangulated = false)
{
typedef typename boost::graph_traits<Graph>::vertices_size_type Size_type;
typedef typename boost::property_traits<typename boost::property_map<Graph, vertex_point_t>::type>::value_type Point;
return make_grid(w, h, g, internal::Default_grid_maker<Size_type, Point>(), triangulated);
}
namespace internal {
template<typename FaceGraph>
@ -1556,10 +875,86 @@ bool is_empty(const FaceGraph& g)
return boost::empty(vertices(g));
}
/// \ingroup PkgBGLHelperFct
///
/// \brief returns the number of calls to `next()` one has to apply to the halfedge `hd`
/// for `source(hd, mesh) == vd` to be true, starting from `hd = halfedge(fd, tm)`.
///
/// \tparam Graph a model of `FaceGraph`
///
/// \param vd a vertex of `g` whose index is sought
/// \param fd a face of `g` in which the index of `vd` is sought
/// \param g a mesh of type `Graph`
///
/// \pre `vd` is a vertex of `fd`.
template <typename Graph>
int vertex_index_in_face(const typename boost::graph_traits<Graph>::vertex_descriptor vd,
const typename boost::graph_traits<Graph>::face_descriptor fd,
const Graph& g)
{
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
halfedge_descriptor start = halfedge(fd, g);
halfedge_descriptor current = start;
int counter = 0;
do
{
if(source(current, g) == vd)
break;
++counter;
current = next(current, g);
}
while(current != start);
if(counter != 0 && current == start)
{
CGAL_assertion_msg(false, "Could not find vertex in face");
return -1;
}
return counter;
}
/// \ingroup PkgBGLHelperFct
///
/// \brief returns the number of calls to `next(hd, tm)` one has to apply to `hd` for `hd == he`
/// to be true, starting from `hd = halfedge(face(he, tm), tm)`.
///
/// \tparam Graph a model of `FaceGraph`.
///
/// \param he a halfedge of `g` whose index in `face(he, tm)` is sought
/// \param g an object of type `Graph`
///
template <typename Graph>
int halfedge_index_in_face(typename boost::graph_traits<Graph>::halfedge_descriptor he,
const Graph& g)
{
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<Graph>::face_descriptor face_descriptor;
CGAL_precondition(he != boost::graph_traits<Graph>::null_halfedge());
CGAL_precondition(!is_border(he, g));
face_descriptor f = face(he, g);
halfedge_descriptor start = halfedge(f, g);
halfedge_descriptor current = start;
int count = 0;
while(current != he)
{
current = next(current, g);
++count;
}
return count;
}
} // namespace CGAL
// Include "Euler_operations.h" at the end, because its implementation
// requires this header.
#include <CGAL/boost/graph/Euler_operations.h>
// Here at the bottom because helpers.h must include generators (for backward compatibility reasons),
// and Euler_operations.h needs helpers.h
#include <CGAL/boost/graph/generators.h>
#endif // CGAL_BOOST_GRAPH_HELPERS_H

View File

@ -83,6 +83,7 @@ CGAL_add_named_parameter(output_iterator_t, output_iterator, output_iterator)
CGAL_add_named_parameter(erase_all_duplicates_t, erase_all_duplicates, erase_all_duplicates)
CGAL_add_named_parameter(require_same_orientation_t, require_same_orientation, require_same_orientation)
CGAL_add_named_parameter(face_size_map_t, face_size_map, face_size_map)
CGAL_add_named_parameter(snapping_tolerance_t, snapping_tolerance, snapping_tolerance)
// List of named parameters that we use in the package 'Surface Mesh Simplification'
CGAL_add_named_parameter(get_cost_policy_t, get_cost_policy, get_cost)

View File

@ -18,5 +18,6 @@ Modular_arithmetic
Number_types
Profiling_tools
Property_map
Random_numbers
STL_Extension
Stream_support

View File

@ -1,4 +1,5 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/boost/graph/graph_traits_Triangulation_2.h>
#include <CGAL/boost/graph/graph_traits_Constrained_triangulation_2.h>
#include <CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h>
@ -40,6 +41,8 @@ void concept_check_triangulation()
boost::function_requires< CGAL::HalfedgeListGraphConcept<T> >();
boost::function_requires< CGAL::FaceGraphConcept<T> >();
boost::function_requires< CGAL::FaceListGraphConcept<T> >();
// Triangulations are not mutable graphs
// boost::function_requires< CGAL::MutableHalfedgeGraphConcept<T> >();
// boost::function_requires< CGAL::MutableFaceGraphConcept<T> >();

View File

@ -2,9 +2,13 @@
#include <CGAL/boost/graph/internal/Has_member_id.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Polyhedron_items_with_id_3.h>
#include <CGAL/Triangulation_vertex_base_with_id_2.h>
#include <CGAL/Triangulation_face_base_with_id_2.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Polyhedron_3<K> Polyhedron;
typedef CGAL::Polyhedron_3<K, CGAL::Polyhedron_items_with_id_3> Polyhedron_with_ids;
@ -32,5 +36,9 @@ int main()
CGAL_static_assertion(
(Has_member_id<Polyhedron_with_ids::Items::Face_wrapper<Polyhedron_with_ids::HDS, K>::Face>::value));
CGAL_static_assertion(!Has_member_id<CGAL::Triangulation_face_base_2<K> >::value);
CGAL_static_assertion(Has_member_id<CGAL::Triangulation_vertex_base_with_id_2<K> >::value);
CGAL_static_assertion(Has_member_id<CGAL::Triangulation_face_base_with_id_2<K> >::value);
return 0;
}

View File

@ -1,8 +1,6 @@
#ifndef CGAL_TEST_PREFIX_H
#define CGAL_TEST_PREFIX_H
#define CGAL_USE_SURFACE_MESH
#include <vector>
#include <fstream>
@ -12,14 +10,34 @@
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Polyhedron_items_with_id_3.h>
#include <CGAL/Linear_cell_complex_for_bgl_combinatorial_map_helper.h>
#include <CGAL/boost/graph/graph_traits_Linear_cell_complex_for_combinatorial_map.h>
#include <CGAL/boost/graph/properties_Linear_cell_complex_for_combinatorial_map.h>
#ifdef CGAL_USE_SURFACE_MESH
#include <CGAL/Surface_mesh.h>
#include <CGAL/Surface_mesh/IO.h>
#endif
#include <CGAL/Constrained_triangulation_face_base_2.h>
#include <CGAL/Constrained_triangulation_plus_2.h>
#include <CGAL/Triangulation_data_structure_2.h>
#include <CGAL/Triangulation_vertex_base_with_id_2.h>
#include <CGAL/Triangulation_face_base_with_id_2.h>
#include <CGAL/Triangulation_hierarchy_vertex_base_2.h>
#include <CGAL/boost/graph/graph_traits_Triangulation_2.h>
#include <CGAL/boost/graph/properties_Triangulation_2.h>
#include <CGAL/boost/graph/graph_traits_Triangulation_hierarchy_2.h>
#include <CGAL/boost/graph/properties_Triangulation_hierarchy_2.h>
#include <CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h>
#include <CGAL/boost/graph/properties_Delaunay_triangulation_2.h>
#include <CGAL/boost/graph/graph_traits_Regular_triangulation_2.h>
#include <CGAL/boost/graph/properties_Regular_triangulation_2.h>
#include <CGAL/boost/graph/graph_traits_Constrained_triangulation_2.h>
#include <CGAL/boost/graph/properties_Constrained_triangulation_2.h>
#include <CGAL/boost/graph/graph_traits_Constrained_Delaunay_triangulation_2.h>
#include <CGAL/boost/graph/properties_Constrained_Delaunay_triangulation_2.h>
#include <CGAL/boost/graph/graph_traits_Constrained_triangulation_plus_2.h>
#include <CGAL/boost/graph/properties_Constrained_triangulation_plus_2.h>
#include <CGAL/boost/graph/io.h>
@ -37,10 +55,7 @@ typedef CGAL::Linear_cell_complex_traits<3, Kernel> MyTraits;
typedef CGAL::Linear_cell_complex_for_bgl_combinatorial_map_helper
<2, 3, MyTraits>::type LCC;
#ifdef CGAL_USE_SURFACE_MESH
typedef CGAL::Surface_mesh<Point_3> SM;
#endif
#if defined(CGAL_USE_OPENMESH)
@ -55,6 +70,31 @@ typedef CGAL::Surface_mesh<Point_3> SM;
typedef OpenMesh::PolyMesh_ArrayKernelT</* MyTraits*/> OMesh;
#endif
typedef CGAL::Triangulation_vertex_base_with_id_2<Kernel> Vbb;
typedef CGAL::Triangulation_face_base_with_id_2<Kernel> Fbb;
typedef CGAL::Triangulation_2<Kernel,
CGAL::Triangulation_data_structure_2<Vbb, Fbb> > Triangulation_2;
typedef CGAL::Delaunay_triangulation_2<Kernel,
CGAL::Triangulation_data_structure_2<Vbb, Fbb> > Delaunay_triangulation_2;
typedef CGAL::Regular_triangulation_vertex_base_2<Kernel, Vbb> RVb;
typedef CGAL::Regular_triangulation_face_base_2<Kernel, Fbb> RFb;
typedef CGAL::Regular_triangulation_2<Kernel,
CGAL::Triangulation_data_structure_2<RVb, RFb> > Regular_triangulation_2;
typedef CGAL::Constrained_triangulation_face_base_2<Kernel, Fbb> CDFb;
typedef CGAL::Triangulation_hierarchy_vertex_base_2<Vbb> CDVb;
typedef CGAL::Constrained_triangulation_2<Kernel,
CGAL::Triangulation_data_structure_2<CDVb, CDFb> > Constrained_triangulation_2;
typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel,
CGAL::Triangulation_data_structure_2<CDVb, CDFb> > Constrained_Delaunay_triangulation_2;
typedef CGAL::Constrained_triangulation_plus_2<
Constrained_Delaunay_triangulation_2> CDT_P2;
typedef CGAL::Triangulation_hierarchy_2<CDT_P2> Triangulation_hierarchy_2;
#include <CGAL/boost/graph/helpers.h>
// helper to easily define all graph_traits members
@ -137,21 +177,46 @@ std::vector<T> t_data()
return vs;
}
std::vector<Polyhedron> poly_data()
{ return t_data<Polyhedron>(); }
#if defined(CGAL_USE_SURFACE_MESH)
std::vector<SM> sm_data()
{ return t_data<SM>(); }
#endif
std::vector<Polyhedron> poly_data() { return t_data<Polyhedron>(); }
std::vector<SM> sm_data() { return t_data<SM>(); }
std::vector<LCC> lcc_data() { return t_data<LCC>(); }
#if defined(CGAL_USE_OPENMESH)
std::vector<OMesh> omesh_data()
{ return t_data<OMesh>(); }
std::vector<OMesh> omesh_data() { return t_data<OMesh>(); }
#endif
std::vector<LCC> lcc_data()
{ return t_data<LCC>(); }
template <typename Tr>
Tr build_dummy_triangulation()
{
typedef typename Tr::Point Point;
typedef typename boost::graph_traits<Tr>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<Tr>::face_descriptor face_descriptor;
Tr t;
t.insert(Point(0.1,0));
t.insert(Point(1,0));
t.insert(Point(0.2,0.2));
t.insert(Point(0,1));
t.insert(Point(0,2));
int id = 0;
for(vertex_descriptor vd : vertices(t))
vd->id() = id++;
id = 0;
for(face_descriptor fd : faces(t))
fd->id() = id++;
return t;
}
Triangulation_2 t2_data() { return build_dummy_triangulation<Triangulation_2>(); }
Delaunay_triangulation_2 dt2_data() { return build_dummy_triangulation<Delaunay_triangulation_2>(); }
Regular_triangulation_2 rt2_data() { return build_dummy_triangulation<Regular_triangulation_2>(); }
Constrained_triangulation_2 ct2_data() { return build_dummy_triangulation<Constrained_triangulation_2>(); }
Constrained_Delaunay_triangulation_2 cdt2_data() { return build_dummy_triangulation<Constrained_Delaunay_triangulation_2>(); }
CDT_P2 cdtp2_data() { return build_dummy_triangulation<CDT_P2>(); }
Triangulation_hierarchy_2 t2h_data() { return build_dummy_triangulation<Triangulation_hierarchy_2>(); }
template <typename Graph>
struct Surface_fixture_1 {

View File

@ -1,5 +1,5 @@
#include "test_Prefix.h"
#include <boost/unordered_set.hpp>
template< typename G,
@ -31,7 +31,6 @@ void index_uniqueness(const G&,
void index_uniqueness_poly(const Polyhedron& g)
{
std::cerr << "testing Polyhedron\n";
index_uniqueness(g, edges(g) , get(boost::edge_index, g));
index_uniqueness(g, vertices(g), get(boost::vertex_index, g));
index_uniqueness(g, faces(g), get(boost::face_index, g));
@ -45,28 +44,23 @@ void index_uniqueness_poly(const Polyhedron& g)
void index_uniqueness_lcc(const LCC& g)
{
std::cerr << "testing Linear_cell_complex\n";
index_uniqueness(g, edges(g) , get(boost::edge_index, g));
index_uniqueness(g, vertices(g), get(boost::vertex_index, g));
index_uniqueness(g, faces(g), get(boost::face_index, g));
index_uniqueness(g, halfedges(g), get(boost::halfedge_index, g));
}
#if defined(CGAL_USE_SURFACE_MESH)
void index_uniqueness_sm(const SM& g)
{
std::cerr << "testing Surface_mesh\n";
index_uniqueness(g, edges(g) , get(boost::edge_index, g));
index_uniqueness(g, vertices(g), get(boost::vertex_index, g));
index_uniqueness(g, faces(g), get(boost::face_index, g));
index_uniqueness(g, halfedges(g), get(boost::halfedge_index, g));
}
#endif
#if defined(CGAL_USE_OPENMESH)
void index_uniqueness_omesh(const OMesh& g)
{
std::cerr << "testing OpenMesh\n";
index_uniqueness(g, edges(g) , get(boost::edge_index, g));
index_uniqueness(g, vertices(g), get(boost::vertex_index, g));
index_uniqueness(g, faces(g), get(boost::face_index, g));
@ -74,35 +68,48 @@ void index_uniqueness_omesh(const OMesh& g)
}
#endif
int
main()
template <typename Triangulation>
void index_uniqueness_tr(const Triangulation& g)
{
index_uniqueness(g, edges(g) , get(boost::edge_index, g));
index_uniqueness(g, vertices(g), get(boost::vertex_index, g));
index_uniqueness(g, faces(g), get(boost::face_index, g));
index_uniqueness(g, halfedges(g), get(boost::halfedge_index, g));
}
int main()
{
std::cout << "testing Polyhedron\n";
std::vector<Polyhedron> polys = poly_data();
for(Polyhedron p : polys){
for(Polyhedron p : polys)
index_uniqueness_poly(p);
}
std::cout << "testing Linear_cell_complex\n";
std::vector<LCC> lccs = lcc_data();
for(LCC p : lccs){
for(LCC p : lccs)
index_uniqueness_lcc(p);
}
#if defined(CGAL_USE_SURFACE_MESH)
std::cout << "testing Surface_mesh\n";
std::vector<SM> sms = sm_data();
for(SM p : sms){
for(SM p : sms)
index_uniqueness_sm(p);
}
#endif
#if defined(CGAL_USE_OPENMESH)
std::cout << "testing OpenMesh\n";
std::vector<OMesh> omeshs = omesh_data();
for(OMesh p : omeshs){
for(OMesh p : omeshs)
index_uniqueness_omesh(p);
}
#endif
std::cout << "testing Triangulations\n";
index_uniqueness_tr(t2_data());
index_uniqueness_tr(dt2_data());
index_uniqueness_tr(rt2_data());
index_uniqueness_tr(ct2_data());
index_uniqueness_tr(cdt2_data());
index_uniqueness_tr(cdtp2_data());
index_uniqueness_tr(t2h_data());
std::cerr << "done\n";
return 0;
}

View File

@ -88,6 +88,7 @@ void test(const NamedParameters& np)
assert(get_param(np, CGAL::internal_np::require_same_orientation).v == 49);
assert(get_param(np, CGAL::internal_np::use_bool_op_to_clip_surface).v == 50);
assert(get_param(np, CGAL::internal_np::face_size_map).v == 52);
assert(get_param(np, CGAL::internal_np::snapping_tolerance).v == 57);
// Named parameters that we use in the package 'Surface Mesh Simplification'
assert(get_param(np, CGAL::internal_np::get_cost_policy).v == 34);
@ -169,6 +170,7 @@ void test(const NamedParameters& np)
check_same_type<49>(get_param(np, CGAL::internal_np::require_same_orientation));
check_same_type<50>(get_param(np, CGAL::internal_np::use_bool_op_to_clip_surface));
check_same_type<52>(get_param(np, CGAL::internal_np::face_size_map));
check_same_type<57>(get_param(np, CGAL::internal_np::snapping_tolerance));
// Named parameters that we use in the package 'Surface Mesh Simplification'
check_same_type<34>(get_param(np, CGAL::internal_np::get_cost_policy));
@ -254,6 +256,7 @@ int main()
.erase_all_duplicates(A<48>(48))
.require_same_orientation(A<49>(49))
.face_size_map(A<52>(52))
.snapping_tolerance(A<57>(57))
);
return EXIT_SUCCESS;

View File

@ -1,11 +1,11 @@
#include "test_Prefix.h"
#include <boost/numeric/conversion/cast.hpp>
#include <boost/unordered_set.hpp>
#include <CGAL/use.h>
typedef boost::unordered_set<std::size_t> id_map;
#include <boost/numeric/conversion/cast.hpp>
#include <boost/unordered_set.hpp>
typedef boost::unordered_set<std::size_t> id_map;
template <typename Graph>
void test_isolated_vertex()
@ -58,6 +58,29 @@ void test_halfedge_around_face_iterator(const Graph& g)
}
}
template<typename G>
void test_halfedge_iterators(const G& g)
{
typedef boost::graph_traits< G > Traits;
typedef typename Traits::halfedge_iterator halfedge_iterator;
typedef typename Traits::halfedges_size_type halfedges_size_type;
// do we iterate as many as that?
halfedge_iterator hb, he;
boost::tie(hb, he) = halfedges(g);
assert(boost::numeric_cast<halfedges_size_type>(std::distance(hb, he)) == num_halfedges(g));
id_map ids;
unsigned int count = 0;
for(boost::tie(hb, he) = halfedges(g); hb != he; ++hb) {
std::pair<id_map::iterator, bool> r = ids.insert(get(boost::halfedge_index, g, *hb));
// unique?
assert(r.second);
++count;
}
assert(count == num_halfedges(g));
}
template<typename G>
void test_edge_iterators(const G& g)
{
@ -86,7 +109,7 @@ void test_edge_iterators(const G& g)
}
template<typename G>
void test_vertex_iterators(G& g)
void test_vertex_iterators(const G& g)
{
typedef boost::graph_traits< G > Traits;
typedef typename Traits::vertex_iterator vertex_iterator;
@ -203,6 +226,41 @@ void test_in_out_edges(const G& g)
}
}
template<typename G>
void test_adjacent_vertices(const G& g)
{
typedef boost::graph_traits< G > Traits;
typedef typename Traits::vertex_descriptor vertex_descriptor;
typedef typename Traits::edge_descriptor edge_descriptor;
typedef typename Traits::in_edge_iterator in_edge_iterator;
typedef typename Traits::out_edge_iterator out_edge_iterator;
typedef typename Traits::adjacency_iterator adjacency_iterator;
typedef std::pair<edge_descriptor, bool> ret;
vertex_descriptor v = *(vertices(g).begin());
adjacency_iterator vb, ve;
boost::tie(vb, ve) = adjacent_vertices(v, g);
in_edge_iterator ieb, iee;
boost::tie(ieb, iee) = in_edges(v, g);
out_edge_iterator oeb, oee;
boost::tie(oeb, oee) = out_edges(v, g);
assert(std::distance(vb, ve) == std::distance(ieb, iee));
assert(std::distance(vb, ve) == std::distance(oeb, oee));
for(; vb != ve; ++vb)
{
vertex_descriptor s = *vb;
assert(s != v);
assert(s != Traits::null_vertex());
ret found = edge(s, v, g);
assert(found.second);
}
}
// check that every edge can be found through edge(u, v, g)
template<typename G>
void test_edge_find(const G& g)
@ -256,39 +314,56 @@ void test_read(const G& g)
assert(CGAL::is_valid_polygon_mesh(g));
}
template <typename Graph>
void
test(const std::vector<Graph>& graphs)
void test_const_graph(const Graph& g)
{
for(const Graph& p : graphs){
test_edge_iterators(p);
test_read(p);
test_vertex_iterators(p);
test_out_edges(p);
test_in_edges(p);
test_in_out_edges(p);
test_edge_find(p);
test_faces(p);
test_halfedge_around_vertex_iterator(p);
test_halfedge_around_face_iterator(p);
}
test_isolated_vertex<Graph>();
test_vertex_iterators(g);
test_halfedge_iterators(g);
test_edge_iterators(g);
test_read(g);
test_out_edges(g);
test_in_edges(g);
test_in_out_edges(g);
// test_adjacent_vertices(g);
test_edge_find(g);
test_faces(g);
test_halfedge_around_vertex_iterator(g);
test_halfedge_around_face_iterator(g);
}
int
main()
template <typename Graph>
void test_graph_range(const std::vector<Graph>& graphs)
{
test(poly_data());
for(const Graph& g : graphs)
{
test_const_graph(g);
test_isolated_vertex<Graph>();
}
}
test(lcc_data());
int main()
{
std::cout << "Test polyhedron data..." << std::endl;
test_graph_range(poly_data());
#if defined(CGAL_USE_SURFACE_MESH)
test(sm_data());
#endif
std::cout << "Test LCC data..." << std::endl;
test_graph_range(lcc_data());
std::cout << "Test Surface_mesh data..." << std::endl;
test_graph_range(sm_data());
std::cout << "Test T2 data..." << std::endl;
test_const_graph(t2_data());
test_const_graph(dt2_data());
test_const_graph(rt2_data());
test_const_graph(ct2_data());
test_const_graph(cdt2_data());
test_const_graph(cdtp2_data());
test_const_graph(t2h_data());
#if defined(CGAL_USE_OPENMESH)
test(omesh_data());
std::cout << "Test OpenMesh data..." << std::endl;
test_graph_range(omesh_data());
#endif
std::cerr << "done" << std::endl;

View File

@ -1,40 +1,31 @@
#include <iostream>
#include <fstream>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/boost/graph/graph_traits_Surface_mesh.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/boost/graph/generators.h>
#include <CGAL/boost/graph/helpers.h>
#include <CGAL/boost/graph/Euler_operations.h>
typedef CGAL::Simple_cartesian<double> K;
typedef K::Point_3 Point_3;
#include <iostream>
#include <fstream>
typedef CGAL::Simple_cartesian<double> K;
typedef K::Point_3 Point_3;
template <typename Mesh>
void
test(const char *fname, bool triangle, bool quad, bool tetrahedron, bool hexahedron)
void test_validity()
{
typedef typename boost::graph_traits<Mesh>::halfedge_descriptor halfedge_descriptor;
std::cerr << "test(" << fname << ")"<< std::endl;
Mesh m;
std::ifstream in(fname);
in >> m;
halfedge_descriptor hd = *halfedges(m).first;
assert(CGAL::is_isolated_triangle(hd, m) == triangle);
assert(CGAL::is_isolated_quad(hd, m) == quad);
assert(CGAL::is_tetrahedron(hd, m) == tetrahedron);
assert(CGAL::is_hexahedron(hd, m) == hexahedron);
}
std::cerr << "test validity" << std::endl;
template <typename Mesh>
void
test_validity(Mesh& mesh)
{
typedef typename boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<Mesh>::edge_descriptor edge_descriptor;
typedef typename boost::graph_traits<Mesh>::face_descriptor face_descriptor;
typedef typename boost::property_map<Mesh, CGAL::vertex_point_t>::type VPMap;
Mesh mesh;
VPMap vpmap = get(CGAL::vertex_point, mesh);
vertex_descriptor vertices[4];
edge_descriptor edges[4];
vertices[0] = add_vertex(mesh);
@ -100,11 +91,32 @@ test_validity(Mesh& mesh)
}
int main()
template <typename Mesh>
void test(const char *fname, bool triangle, bool quad, bool tetrahedron, bool hexahedron)
{
typedef CGAL::Surface_mesh<Point_3> Mesh;
Mesh mesh;
test_validity(mesh);
typedef typename boost::graph_traits<Mesh>::halfedge_descriptor halfedge_descriptor;
std::cerr << "test(" << fname << ")"<< std::endl;
Mesh m;
std::ifstream in(fname);
in >> m;
halfedge_descriptor hd = *halfedges(m).first;
assert(CGAL::is_isolated_triangle(hd, m) == triangle);
assert(CGAL::is_isolated_quad(hd, m) == quad);
assert(CGAL::is_tetrahedron(hd, m) == tetrahedron);
assert(CGAL::is_hexahedron(hd, m) == hexahedron);
}
template <typename Mesh>
void test_generators()
{
typedef typename boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<Mesh>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<Mesh>::edge_descriptor edge_descriptor;
typedef typename boost::graph_traits<Mesh>::face_descriptor face_descriptor;
// triangle quad tetra hexa
test<Mesh>("data/triangle.off", true, false, false, false );
test<Mesh>("data/quad.off", false, true, false, false );
@ -112,20 +124,21 @@ int main()
test<Mesh>("data/cube.off", false, false, false, false );
test<Mesh>("data/cube-quads.off", false, false, false, true );
typedef boost::graph_traits<Mesh>::halfedge_descriptor halfedge_descriptor;
Point_3 a(0,0,0), b(1,0,0), c(1,1,0), d(0,1,0);
Point_3 aa(0,0,1), bb(1,0,1), cc(1,1,1), dd(0,1,1);
Mesh m;
halfedge_descriptor hd;
hd = CGAL::make_triangle(a,b,c,m);
assert(CGAL::is_isolated_triangle(hd,m));
assert(CGAL::is_valid_polygon_mesh(m));
m.clear();
hd = CGAL::make_quad(a,b,c,d,m);
assert(CGAL::is_isolated_quad(hd,m));
assert(CGAL::is_valid_polygon_mesh(m));
assert(CGAL::is_quad_mesh(m));
m.clear();
hd = CGAL::make_tetrahedron(a,b,c,d,m);
assert(CGAL::is_tetrahedron(hd,m));
@ -136,26 +149,86 @@ int main()
assert(CGAL::is_hexahedron(hd,m));
assert(CGAL::is_quad_mesh(m));
assert(CGAL::is_valid_polygon_mesh(m));
m.clear();
CGAL::make_icosahedron<Mesh, Point_3>(m);
assert(num_faces(m) == 20);
assert(CGAL::is_triangle_mesh(m));
assert(CGAL::is_valid_polygon_mesh(m));
m.clear();
hd = CGAL::make_pyramid<Mesh, Point_3>(3, m);
assert(num_faces(m) == 6);
assert(CGAL::is_triangle_mesh(m));
assert(CGAL::is_valid_polygon_mesh(m));
m.clear();
hd = CGAL::make_regular_prism<Mesh, Point_3>(4, m);
assert(num_faces(m) == 16);
assert(CGAL::is_triangle_mesh(m));
assert(CGAL::is_valid_polygon_mesh(m));
m.clear();
CGAL::make_grid(3,3,m);
assert(num_faces(m) == 9);
assert(CGAL::is_quad_mesh(m));
assert(CGAL::is_valid_polygon_mesh(m));
std::cerr << "done" << std::endl;
return 0;
// -----------------------------------------------------------------------------------------------
std::cerr << "test random element generators" << std::endl;
vertex_descriptor v;
halfedge_descriptor h;
edge_descriptor e;
face_descriptor f;
CGAL::Random rnd;
// ---------------------------------------------------------------------------
v = CGAL::internal::random_vertex_in_mesh(m, rnd);
assert(v != boost::graph_traits<Mesh>::null_vertex());
h = CGAL::internal::random_halfedge_in_mesh(m, rnd);
assert(h != boost::graph_traits<Mesh>::null_halfedge());
e = CGAL::internal::random_edge_in_mesh(m, rnd);
f = CGAL::internal::random_face_in_mesh(m, rnd);
assert(f != boost::graph_traits<Mesh>::null_face());
// ---------------------------------------------------------------------------
h = CGAL::internal::random_halfedge_in_face(f, m, rnd);
assert(h != boost::graph_traits<Mesh>::null_halfedge());
assert(face(h, m) == f);
v = CGAL::internal::random_vertex_in_face(f, m, rnd);
assert(v != boost::graph_traits<Mesh>::null_vertex());
// could use vertices_around_face, but it's the point is not to
bool has_vertex = false;
halfedge_descriptor done = h;
do
{
if(target(h, m) == v)
{
has_vertex = true;
break;
}
h = next(h, m);
}
while(h != done);
assert(has_vertex);
}
int main()
{
typedef CGAL::Surface_mesh<Point_3> Mesh;
test_validity<Mesh>();
test_generators<Mesh>();
std::cerr << "done" << std::endl;
return EXIT_SUCCESS;
}

View File

@ -28,6 +28,7 @@ Polyhedron
Polyhedron_IO
Profiling_tools
Property_map
Random_numbers
STL_Extension
Spatial_sorting
Stream_support

View File

@ -55,6 +55,7 @@
#include <CGAL/internal/Exact_type_selector.h>
#include <CGAL/boost/graph/copy_face_graph.h>
#include <CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h>
#include <CGAL/boost/graph/properties_Triangulation_data_structure_2.h>
#include <CGAL/Polyhedron_3_fwd.h>
#include <CGAL/boost/graph/Euler_operations.h>

View File

@ -14,6 +14,7 @@ Number_types
Polygon_mesh_processing
Profiling_tools
Property_map
Random_numbers
STL_Extension
Solver_interface
Stream_support

View File

@ -24,7 +24,16 @@ Release date: September 2019
for all vertices, which enables to use C++11 for-loops.
- **Breaking change**: The constructor and the `insert()` function of `CGAL::Triangulation_3` which takes
a range of points as argument no longer performs a `spatial_sort()` of the points.
- Add constructor and `insert()` function to `CGAL::Triangulation_3` that takes a range of points with info.
- Added constructor and `insert()` function to `CGAL::Triangulation_3` that takes a range of points with info.
- **breaking change** The graph traits enabling CGAL's 2D triangulations to be used as a parameter
for any graph-based algorithm of CGAL (or boost) have been improved to fully model the `FaceGraph` concept.
In addition, only the finite simplicies (those not incident to the infinite vertex) of the 2D triangulations
are now visibile through this scope. The complete triangulation can still be accessed as a graph,
by using the graph traits of the underlying triangulation data structure (usually,
`CGAL::Triangulation_data_structure_2`).
- Introduced a new face base class, `Triangulation_face_base_with_id_2` which enables storing
user-defined integer IDs in the face of any 2D triangulation, a precondition to use some
BGL algorithms.
### Surface Mesh
- New functions to read and write using the PLY format,
@ -42,6 +51,11 @@ Release date: September 2019
Parameters.
### Polygon Mesh Processing
- Introduced a wide range of new functions related to location of queries on a triangle mesh,
such as `CGAL::Polygon_mesh_processing::locate(Point, Mesh)`, . The location of a point on a triangle mesh
is expressed as the pair of a face and the barycentric coordinates of the point in this face,
enabling robust manipulation of locations (for example, intersections of two 3D segments living
within the same face).
- Added the function `CGAL::Polygon_mesh_processing::centroid()`, which computes
the centroid of a closed triangle mesh.
- Added the functions `CGAL::Polygon_mesh_processing::stitch_boundary_cycle()` and

View File

@ -0,0 +1,63 @@
// Copyright (c) 2019 GeometryFactory SARL (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
// Author(s) : Andreas Fabri
//
// Warning: this file is generated, see include/CGAL/licence/README.md
#ifndef CGAL_LICENSE_POLYGON_MESH_PROCESSING_LOCATE_H
#define CGAL_LICENSE_POLYGON_MESH_PROCESSING_LOCATE_H
#include <CGAL/config.h>
#include <CGAL/license.h>
#ifdef CGAL_POLYGON_MESH_PROCESSING_LOCATE_COMMERCIAL_LICENSE
# if CGAL_POLYGON_MESH_PROCESSING_LOCATE_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE
# if defined(CGAL_LICENSE_WARNING)
CGAL_pragma_warning("Your commercial license for CGAL does not cover "
"this release of the Polygon Mesh Processing - Locate package.")
# endif
# ifdef CGAL_LICENSE_ERROR
# error "Your commercial license for CGAL does not cover this release \
of the Polygon Mesh Processing - Locate package. \
You get this error, as you defined CGAL_LICENSE_ERROR."
# endif // CGAL_LICENSE_ERROR
# endif // CGAL_POLYGON_MESH_PROCESSING_LOCATE_COMMERCIAL_LICENSE < CGAL_RELEASE_DATE
#else // no CGAL_POLYGON_MESH_PROCESSING_LOCATE_COMMERCIAL_LICENSE
# if defined(CGAL_LICENSE_WARNING)
CGAL_pragma_warning("\nThe macro CGAL_POLYGON_MESH_PROCESSING_LOCATE_COMMERCIAL_LICENSE is not defined."
"\nYou use the CGAL Polygon Mesh Processing - Locate package under "
"the terms of the GPLv3+.")
# endif // CGAL_LICENSE_WARNING
# ifdef CGAL_LICENSE_ERROR
# error "The macro CGAL_POLYGON_MESH_PROCESSING_LOCATE_COMMERCIAL_LICENSE is not defined.\
You use the CGAL Polygon Mesh Processing - Locate package under the terms of \
the GPLv3+. You get this error, as you defined CGAL_LICENSE_ERROR."
# endif // CGAL_LICENSE_ERROR
#endif // no CGAL_POLYGON_MESH_PROCESSING_LOCATE_COMMERCIAL_LICENSE
#endif // CGAL_LICENSE_CHECK_POLYGON_MESH_PROCESSING_LOCATE_H

View File

@ -8,7 +8,6 @@
#include <utility>
#include <vector>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::FT Coord_type;
typedef K::Point_2 Point;
@ -21,12 +20,20 @@ int main()
{
Delaunay_triangulation dt;
for(int y=0; y<3; ++y)
for(int x=0; x<3; ++x)
dt.insert(K::Point_2(x, y));
// for(int y=0; y<3; ++y)
// for(int x=0; x<3; ++x)
// dt.insert(K::Point_2(x, y));
dt.insert(K::Point_2(50.18, -61.82));
dt.insert(K::Point_2(50.18, -61.80));
dt.insert(K::Point_2(10, -61));
dt.insert(K::Point_2(70, -61));
dt.insert(K::Point_2(50, -30));
dt.insert(K::Point_2(50, -90));
// coordinates computation
K::Point_2 p(1.2, 0.7); // query point
K::Point_2 p(50.18, -61.82); // query point
Point_coordinate_vector coords;
CGAL::Triple<std::back_insert_iterator<Point_coordinate_vector>, K::FT, bool> result =
@ -42,9 +49,10 @@ int main()
std::cout << "Coordinate computation successful." << std::endl;
std::cout << "Normalization factor: " << norm << std::endl;
std::cout << "Coordinates for point: (" << p << ") are the following: " << std::endl;
for(std::size_t i=0; i<coords.size(); ++i)
std::cout << " Point: (" << coords[i].first << ") coeff: " << coords[i].second << std::endl;
return EXIT_SUCCESS;
return 0;
}

View File

@ -23,5 +23,6 @@ Modular_arithmetic
Number_types
Profiling_tools
Property_map
Random_numbers
STL_Extension
Stream_support

View File

@ -29,6 +29,7 @@ Polyhedron
Polyhedron_IO
Profiling_tools
Property_map
Random_numbers
STL_Extension
Spatial_sorting
Stream_support

View File

@ -28,6 +28,7 @@ Polyhedron
Polyhedron_IO
Profiling_tools
Property_map
Random_numbers
STL_Extension
Spatial_sorting
Stream_support

View File

@ -225,7 +225,7 @@ all objects, predicates and constructions with using offsets.
The class
`Periodic_2_Delaunay_triangulation_traits_2<Traits,Periodic_2Offset_2>`
provides the required functionality. It expects two template
parameters: A model of the concept `DelaunayTriangulationTraits_2`
parameters: a model of the concept `DelaunayTriangulationTraits_2`
and a model of the concept `Periodic_2Offset_2`. Since the concept
`TriangulationTraits_2` refines the concept
`DelaunayTriangulationTraits_2`, the class

View File

@ -390,6 +390,17 @@ if orientation should matter when determining whether two faces are duplicates.
<b>Default:</b> `false`
\cgalNPEnd
\cgalNPBegin{snapping_tolerance} \anchor PMP_snapping_tolerance
Parameter used in the function `locate_in_face()` to to snap barycentric coordinates. Depending on the geometric traits used,
the computation of the barycentric coordinates might be an inexact construction, thus leading
to sometimes surprising values (e.g. a triplet `[0.5, 0.5, -1-e17]` for a point at the middle
of an edge). The coordinates will be snapped towards `0` and `1` if the difference is smaller than the tolerance value, while
still ensuring that the total sum of the coordinates is `1`.
\n
<b>Type:</b> `Kernel::FT` \n
<b>Default:</b> `0`
\cgalNPEnd
\cgalNPBegin{face_size_map} \anchor PMP_face_size_map
Parameter used in the functions `keep_large_connected_components()` and
`keep_largest_connected_components()` to pass a property map that gives the size of a face when

View File

@ -54,6 +54,10 @@
/// Functions to detect sharp edges and surface patches of polygon meshes.
/// \ingroup PkgPolygonMeshProcessingRef
/// \defgroup PMP_locate_grp Location Functions
/// Functions to locate points on a mesh, and manipulate such locations.
/// \ingroup PkgPolygonMeshProcessingRef
/// \defgroup PMP_predicates_grp Intersection Detection Functions
/// Functions to detect intersections.
/// Note that those functions will be exact as long as the underlying do-intersect predicates used are exact.
@ -121,6 +125,12 @@ and provides a list of the parameters that are used in this package.
- `CGAL::Polygon_mesh_processing::is_needle_triangle_face()`
- `CGAL::Polygon_mesh_processing::is_cap_triangle_face()`
\cgalCRPSection{Location Functions}
- \link PMP_locate_grp Point Location \endlink
- \link PMP_locate_grp Location Predicates \endlink
- \link PMP_locate_grp Nearest Face Location Queries \endlink
- \link PMP_locate_grp Random Location Generation \endlink
\cgalCRPSection{Orientation Functions}
- `CGAL::Polygon_mesh_processing::orient_polygon_soup()`
- `CGAL::Polygon_mesh_processing::orient()`

View File

@ -463,6 +463,24 @@ This package offers a toolkit of functions to detect such undesirable elements.
- `CGAL::Polygon_mesh_processing::is_cap_triangle_face()`
- `CGAL::Polygon_mesh_processing::is_needle_triangle_face()`
\subsection PMPLocationFunctions Surface Location Functions
To ease the manipulation of points on a surface, \cgal offers a multitude of functions based upon
a different representation of a point on a polygon mesh: the point is represented as a pair of
a face of the polygon mesh and a triplet of barycentric coordinates. This definition enables
a robust handling of polylines between points living in the same face: for example, two 3D segments
created by four points within the same face that should intersect might not actually intersect due to
inexact computations. However, manipulating these same points through their barycentric coordinates
can instead be done, and intersections computed in the barycentric space will not suffer
from the same issues. Furthermore, this definition is only dependent on the intrinsic dimension
of the surface (i.e. 2) and not on the ambient dimension within which the surface is embedded.
The functions of the group \ref PMP_locate_grp offer the following functionalities:
location computations (`CGAL::Polygon_mesh_processing::locate()`, and similar) given a point,
finding the nearest point on a mesh given a point or a ray
(`CGAL::Polygon_mesh_processing::locate_with_AABB_tree()`, and similar), and location-based predicates
(for example, `CGAL::Polygon_mesh_processing::is_on_face_border()`).
****************************************
\section PMPOrientation Orientation

File diff suppressed because it is too large Load Diff

View File

@ -88,6 +88,7 @@ endif()
create_single_source_cgal_program("test_repair_polygon_soup.cpp")
create_single_source_cgal_program("test_shape_predicates.cpp")
create_single_source_cgal_program("test_pmp_collision_detection.cpp")
create_single_source_cgal_program("test_pmp_locate.cpp")
create_single_source_cgal_program("test_pmp_snapping.cpp")
create_single_source_cgal_program("test_pmp_non_conforming_snapping.cpp")
create_single_source_cgal_program("remove_degeneracies_test.cpp")

View File

@ -0,0 +1,522 @@
OFF
195 325 0
-0.24592500000000000 0.02013070000000000
-0.23906300000000000 0.00917146000000000
-0.22414600000000001 0.02627040000000000
-0.21665699999999999 0.09137350000000000
-0.20436900000000000 0.13125800000000001
-0.22717399999999999 0.11141900000000000
-0.23814700000000000 -0.00559741000000000
-0.22804700000000000 -0.00611597000000000
-0.23734700000000000 0.00223480000000000
-0.17373700000000000 0.10742100000000000
-0.18601799999999999 0.12388100000000001
-0.28231400000000001 0.05716840000000000
-0.26321000000000000 0.03789740000000000
-0.24498400000000001 0.05559020000000000
-0.20538999999999999 0.04444000000000000
-0.20414800000000000 0.02031610000000000
-0.25870100000000001 0.08402350000000000
-0.26684400000000003 0.10788800000000000
-0.22636600000000001 0.00430057000000000
-0.18667000000000000 0.14006900000000000
-0.16358800000000001 0.13642799999999999
-0.20508599999999999 0.14620600000000000
-0.26247900000000002 0.01860690000000000
-0.24475300000000000 0.00128651000000000
-0.17287900000000000 0.07846690000000001
-0.14485700000000001 0.12063500000000001
-0.13344700000000001 0.15071200000000001
-0.25083600000000000 0.00914945000000000
-0.18010599999999999 0.03686900000000000
-0.18816300000000000 0.02293980000000000
-0.20318600000000001 -0.03005060000000000
-0.17436699999999999 -0.01695920000000000
-0.20029500000000000 -0.00554548000000000
-0.21379000000000001 -0.01019390000000000
-0.22625999999999999 -0.01602680000000000
-0.18674800000000000 -0.00071344700000000
-0.03932460000000000 -0.02666830000000000
-0.03925560000000000 -0.05397620000000000
-0.01404300000000000 -0.05156900000000000
-0.01281140000000000 -0.03297440000000000
0.00025716100000000 -0.04038760000000000
-0.00235339000000000 -0.06635020000000000
0.00514285000000000 -0.02623370000000000
-0.05370540000000000 -0.10002100000000000
-0.06064010000000000 -0.07184490000000000
-0.10332300000000000 -0.09791700000000000
-0.09767480000000001 -0.06580080000000001
-0.02287800000000000 -0.12280500000000000
-0.01834440000000000 -0.10006500000000000
-0.03703030000000000 -0.10977800000000000
-0.22790700000000000 -0.03429780000000000
-0.24421999999999999 -0.02160990000000000
-0.21956100000000001 -0.00229464000000000
-0.01882920000000000 -0.07918520000000000
-0.19679700000000000 0.00930870000000000
-0.17767800000000000 0.01133440000000000
-0.15034600000000001 -0.03228640000000000
-0.09626770000000000 -0.03217010000000000
-0.12686400000000000 -0.01489330000000000
-0.03686590000000000 -0.08920240000000000
-0.04727000000000000 -0.12435800000000000
-0.07423990000000000 -0.11637599999999999
-0.28881000000000001 0.08273820000000000
-0.19542799999999999 -0.05568390000000000
-0.25102000000000002 -0.03770290000000000
-0.25682800000000000 -0.01989910000000000
-0.01044890000000000 -0.11426799999999999
-0.15682900000000000 -0.07004180000000000
-0.15470700000000001 0.02812290000000000
-0.06659100000000000 -0.04315070000000000
-0.06487910000000000 -0.14555499999999999
-0.14442099999999999 -0.11574900000000000
-0.15122400000000000 -0.15927800000000000
-0.11173900000000000 -0.14992600000000000
-0.03111620000000000 -0.14380999999999999
-0.16651299999999999 -0.17455000000000001
-0.13802300000000001 -0.17901800000000001
-0.26305400000000001 -0.03008160000000000
-0.21636000000000000 -0.14896999999999999
-0.21421299999999999 -0.11310099999999999
-0.24318400000000001 -0.14052799999999999
-0.18837999999999999 -0.17875099999999999
-0.18471000000000001 -0.14161699999999999
-0.15202099999999999 0.00089938800000000
-0.27395000000000003 -0.04066720000000000
-0.18671699999999999 -0.09123320000000000
-0.22246400000000000 -0.07536089999999999
-0.09578760000000000 -0.13067799999999999
-0.23696500000000001 0.12865599999999999
-0.25777400000000000 -0.05791230000000000
-0.28615400000000002 0.03984230000000000
-0.00327775000000000 -0.00841017000000000
-0.25280999999999998 -0.00309231000000000
0.00121365000000000 -0.08619950000000000
-0.17146900000000001 -0.00241387000000000
-0.15892999999999999 -0.01343940000000000
-0.21124000000000001 0.00524665000000000
-0.06533350000000000 -0.01421250000000000
-0.21189600000000000 -0.00271869000000000
-0.25108000000000003 -0.09202000000000000
-0.31369799999999998 0.03807740000000000
-0.27149099999999998 -0.11406700000000000
-0.28459699999999999 -0.07320550000000001
-0.07589390000000000 -0.18407699999999999
-0.06261100000000000 -0.17513000000000001
-0.07609330000000000 -0.16314200000000001
0.00016327700000000 -0.10355200000000001
-0.02872410000000000 -0.00156414000000000
-0.01435380000000000 0.00308408000000000
-0.12731200000000001 0.01677310000000000
-0.13466700000000001 0.00094315400000000
0.00202303000000000 0.07827919999999999
0.02841240000000000 0.08494169999999999
0.01594670000000000 0.10307900000000000
-0.00962830000000000 0.14879200000000001
-0.01673320000000000 0.11896400000000000
0.00534235000000000 0.12164000000000000
-0.03012780000000000 0.10138900000000001
-0.02854770000000000 0.07080069999999999
-0.00592029000000000 0.10068500000000000
-0.31689800000000001 0.06285480000000000
-0.00926267000000000 0.01742490000000000
-0.02594480000000000 0.01520790000000000
0.03956540000000000 0.06584290000000000
-0.00259196000000000 0.05460730000000000
-0.04968400000000000 0.01822080000000000
-0.07789880000000000 0.02296420000000000
-0.06690250000000000 0.00647931000000000
-0.04768020000000000 -0.14828000000000000
0.02457530000000000 0.15474499999999999
0.11276600000000001 0.09952060000000000
0.07082629999999999 0.08771039999999999
0.09508170000000001 0.07003930000000000
0.08551670000000000 0.03420360000000000
0.06843790000000000 0.05875820000000000
0.04888310000000000 0.02946740000000000
0.05944330000000000 0.01189650000000000
0.08005260000000000 0.01455180000000000
0.15004899999999999 0.10953400000000001
0.15212899999999999 0.07574839999999999
-0.03531200000000000 0.17809400000000000
-0.05507500000000000 0.15928200000000001
-0.02680130000000000 0.15953400000000001
0.04326160000000000 0.16105800000000001
0.05561930000000000 0.14540500000000001
0.06160470000000000 0.16266600000000001
0.12242400000000001 0.13998200000000000
0.09908670000000000 0.13400400000000001
-0.00513261000000000 0.16801199999999999
0.02864610000000000 0.17255899999999999
0.02302540000000000 0.18896600000000000
0.05399200000000000 0.12448900000000000
0.03694350000000000 0.13911499999999999
0.03778010000000000 0.10418200000000000
0.01162540000000000 0.03488840000000000
-0.05307370000000000 0.13435200000000000
-0.06687100000000000 0.11254300000000000
-0.10134500000000000 0.00172185000000000
0.07658940000000000 0.14677899999999999
0.07598090000000000 0.12629000000000001
0.01506890000000000 0.00949618000000000
-0.08534820000000000 0.08532910000000000
-0.02799170000000000 0.13784500000000000
0.12397300000000000 0.07188710000000000
0.00496704000000000 0.01990390000000000
-0.07667960000000000 0.13824400000000001
-0.09684780000000000 0.11329300000000000
0.07175130000000000 -0.00410704000000000
0.02393600000000000 -0.01454820000000000
0.04050310000000000 0.00510915000000000
-0.02270260000000000 0.04054320000000000
-0.00573450000000000 0.03748440000000000
-0.09173530000000001 0.04960090000000000
-0.05740990000000000 -0.16077300000000000
-0.11552800000000001 0.07408670000000001
0.11186599999999999 0.04843290000000000
-0.12656600000000001 0.10163000000000000
-0.15584899999999999 0.05703930000000000
-0.11467300000000000 -0.17524799999999999
0.00996937000000000 -0.01298980000000000
0.00042625600000000 0.00615835000000000
-0.09476610000000001 -0.17258599999999999
-0.10563200000000000 0.15925500000000001
-0.11695800000000001 0.13199100000000000
-0.12928400000000001 0.04635750000000000
0.04950970000000000 0.17627999999999999
0.03775450000000000 0.18965699999999999
-0.05625970000000000 0.04608740000000000
-0.05938180000000000 0.18434700000000001
-0.07765430000000000 0.16547300000000001
0.05390970000000000 -0.00800927000000000
0.09879780000000001 0.00829006000000000
-0.01792850000000000 0.19112499999999999
0.00412912000000000 0.19402800000000001
-0.28409000000000001 0.02300040000000000
3 0 1 2
3 3 4 5
3 6 7 8
3 9 10 3
3 10 4 3
3 11 12 13
3 14 2 15
3 16 5 17
3 13 12 0
3 18 1 8
3 19 10 20
3 19 21 4
3 22 0 12
3 16 3 5
3 7 18 8
3 1 18 2
3 13 14 3
3 23 8 1
3 9 24 25
3 25 26 20
3 20 9 25
3 3 24 9
3 0 22 27
3 16 13 3
3 28 14 29
3 4 10 19
3 0 27 1
3 14 24 3
3 30 31 32
3 30 33 34
3 35 32 31
3 36 37 38
3 36 38 39
3 40 39 38
3 38 41 40
3 39 40 42
3 43 44 45
3 45 44 46
3 47 48 49
3 50 34 51
3 23 1 27
3 7 33 52
3 38 37 53
3 29 54 55
3 56 57 58
3 59 48 53
3 60 43 61
3 62 11 16
3 55 28 29
3 63 56 31
3 64 51 65
3 66 48 47
3 46 67 45
3 55 68 28
3 49 59 43
3 37 69 44
3 70 60 61
3 71 72 73
3 47 60 74
3 37 44 59
3 50 63 30
3 43 45 61
3 37 36 69
3 72 75 76
3 64 65 77
3 78 79 80
3 78 81 82
3 68 55 83
3 77 84 64
3 6 51 34
3 79 85 86
3 30 34 50
3 56 63 67
3 70 61 87
3 88 17 5
3 84 89 64
3 86 63 50
3 90 12 11
3 33 7 34
3 45 67 71
3 42 91 39
3 92 51 6
3 41 53 93
3 86 64 89
3 94 31 95
3 83 94 95
3 2 18 96
3 69 97 57
3 61 45 87
3 52 98 96
3 99 79 86
3 54 96 32
3 49 48 59
3 38 53 41
3 50 64 86
3 11 100 90
3 82 71 85
3 82 72 71
3 35 54 32
3 78 82 79
3 36 97 69
3 80 99 101
3 98 32 96
3 52 18 7
3 98 33 32
3 102 101 99
3 103 104 105
3 106 48 66
3 107 91 108
3 109 83 110
3 111 112 113
3 34 7 6
3 114 115 116
3 59 44 43
3 117 118 119
3 29 15 54
3 119 118 111
3 62 120 11
3 108 121 122
3 123 111 124
3 125 126 127
3 102 89 84
3 74 60 128
3 116 129 114
3 50 51 64
3 130 131 132
3 35 31 94
3 133 134 135
3 133 136 137
3 83 95 58
3 138 130 139
3 115 117 119
3 86 85 63
3 17 62 16
3 46 57 56
3 107 122 125
3 140 141 142
3 79 99 80
3 143 144 145
3 130 146 147
3 45 71 87
3 148 149 150
3 107 127 97
3 151 152 153
3 123 124 154
3 117 155 156
3 118 124 111
3 56 67 46
3 48 93 53
3 71 73 87
3 107 36 39
3 110 58 157
3 92 65 51
3 60 49 43
3 158 144 159
3 160 135 154
3 161 117 156
3 117 115 162
3 130 132 163
3 29 14 15
3 96 18 52
3 47 49 60
3 160 154 164
3 156 165 166
3 129 149 148
3 52 33 98
3 167 137 136
3 143 152 144
3 46 69 57
3 160 168 169
3 124 170 171
3 136 135 169
3 155 141 165
3 125 122 170
3 30 32 33
3 131 153 112
3 172 109 157
3 134 123 135
3 105 104 173
3 166 174 161
3 142 162 114
3 2 96 15
3 155 117 162
3 59 53 37
3 153 116 113
3 107 39 91
3 23 6 8
3 139 130 163
3 133 135 136
3 163 132 175
3 20 10 9
3 176 24 177
3 72 178 73
3 127 126 157
3 179 180 91
3 178 181 73
3 116 152 129
3 182 26 183
3 68 83 109
3 89 102 99
3 142 114 148
3 118 117 161
3 109 184 68
3 149 185 186
3 187 118 161
3 134 131 123
3 180 108 91
3 126 125 187
3 138 146 130
3 86 89 99
3 157 109 110
3 184 109 172
3 141 188 189
3 157 126 172
3 83 55 94
3 83 58 110
3 172 161 174
3 180 179 160
3 82 75 72
3 93 48 106
3 14 13 2
3 132 133 175
3 97 157 57
3 183 26 25
3 2 13 0
3 120 100 11
3 172 174 184
3 144 151 159
3 165 189 182
3 164 121 180
3 179 168 160
3 16 11 13
3 190 167 136
3 131 112 123
3 166 161 156
3 149 129 143
3 151 153 131
3 170 187 125
3 82 81 75
3 143 145 185
3 153 152 116
3 148 140 142
3 151 144 152
3 95 31 56
3 97 36 107
3 5 4 88
3 73 181 105
3 149 143 185
3 165 141 189
3 112 111 123
3 177 174 176
3 187 170 118
3 174 166 176
3 114 129 148
3 147 158 159
3 85 67 63
3 28 24 14
3 158 145 144
3 159 151 131
3 187 161 172
3 70 173 128
3 55 35 94
3 25 176 183
3 105 173 70
3 154 171 164
3 24 176 25
3 142 141 155
3 55 54 35
3 191 133 137
3 130 159 131
3 162 142 155
3 180 160 164
3 170 122 121
3 147 159 130
3 140 148 192
3 68 177 28
3 21 88 4
3 162 115 114
3 169 190 136
3 87 73 105
3 148 150 193
3 179 91 42
3 175 133 191
3 87 105 70
3 170 121 171
3 116 115 119
3 63 31 30
3 148 193 192
3 149 186 150
3 141 140 188
3 160 169 135
3 118 170 124
3 68 184 177
3 129 152 143
3 132 131 134
3 15 96 54
3 107 125 127
3 113 116 119
3 132 134 133
3 128 60 70
3 56 58 95
3 111 113 119
3 105 181 103
3 164 171 121
3 155 165 156
3 85 71 67
3 177 184 174
3 154 124 171
3 72 76 178
3 135 123 154
3 194 22 12
3 113 112 153
3 79 82 85
3 57 157 58
3 122 107 108
3 121 108 180
3 165 182 183
3 177 24 28
3 166 183 176
3 127 157 97
3 44 69 46
3 90 194 12
3 168 190 169
3 165 183 166
3 172 126 187

View File

@ -0,0 +1,160 @@
0.00605396 0.00360027
0.0117095 0.00496933
0.00292489 -0.0056444
0.018654 -0.00345866
0.0208731 -0.00712699
0.0349622 0.00520127
0.0226514 0.00273598
0.0443469 0.00641652
0.0320264 -0.00785089
0.0536853 -0.00492172
0.0477706 0.00445479
0.0639807 0.00509629
0.0673864 -0.000544755
0.068878 0.00636891
0.0786834 -0.00880306
0.0838299 0.00977294
0.087326 -0.0021897
0.079062 0.000772423
0.0984893 0.00905454
0.0994487 -0.00770074
0.100736 0.00717826
0.0994229 0.00250389
0.100252 0.0167278
0.0960604 0.00802011
0.103545 0.0289233
0.108446 0.0183656
0.106763 0.0262313
0.106452 0.0420934
0.0997256 0.0427598
0.107064 0.0403298
0.0928101 0.0560955
0.10136 0.0583232
0.104819 0.0562105
0.0902899 0.0706163
0.10994 0.0770702
0.0923621 0.0704878
0.0919434 0.0865538
0.0963674 0.0842679
0.103725 0.0803259
0.102273 0.101166
0.100319 0.0952791
0.108403 0.0942299
0.113529 0.0981625
0.108027 0.103066
0.126272 0.0950435
0.133506 0.0939314
0.124776 0.107205
0.131076 0.107853
0.136759 0.109119
0.15444 0.102357
0.143707 0.104111
0.160272 0.0974776
0.165379 0.103348
0.173751 0.0916309
0.174657 0.0937715
0.167267 0.0980068
0.170889 0.0905988
0.185414 0.102092
0.189813 0.10002
0.199397 0.0909473
0.198222 0.107717
0.198974 0.099872
0.201479 0.108827
0.205074 0.107075
0.202 0.124977
0.191185 0.121976
0.206848 0.134009
0.196679 0.137767
0.19255 0.148035
0.190151 0.143856
0.195263 0.155428
0.20595 0.148822
0.204421 0.152387
0.191967 0.169495
0.197981 0.169699
0.191872 0.176798
0.207398 0.170317
0.194859 0.178978
0.190444 0.183389
0.196073 0.192833
0.200019 0.190352
0.205824 0.198579
0.217043 0.198723
0.210708 0.208976
0.225591 0.209213
0.224774 0.208331
0.228376 0.201784
0.233852 0.192014
0.230703 0.196273
0.241172 0.192107
0.241027 0.203219
0.257393 0.199803
0.266244 0.190504
0.263176 0.1902
0.279822 0.191442
0.267419 0.200092
0.270919 0.209937
0.294279 0.199399
0.292596 0.208336
0.302111 0.206854
0.297261 0.193606
0.302447 0.195568
0.307461 0.217454
0.302133 0.219113
0.300152 0.216012
0.296763 0.223723
0.302571 0.234727
0.298522 0.237272
0.307834 0.234066
0.296568 0.250613
0.298385 0.251664
0.29308 0.261943
0.295426 0.266549
0.293096 0.259791
0.292439 0.271056
0.291263 0.275271
0.300944 0.286063
0.308624 0.284206
0.306603 0.285177
0.302574 0.289769
0.303807 0.303483
0.308102 0.301263
0.316854 0.306492
0.313448 0.299638
0.325862 0.304911
0.328301 0.305416
0.335535 0.300855
0.327652 0.299601
0.334895 0.301131
0.339451 0.303238
0.356128 0.293215
0.359167 0.306227
0.350648 0.309557
0.359385 0.291005
0.360515 0.305818
0.377582 0.301763
0.373333 0.308693
0.375172 0.299768
0.398744 0.298911
0.390985 0.295462
0.39465 0.305079
0.397266 0.302934
0.391293 0.303944
0.401355 0.307406
0.391301 0.312749
0.401141 0.331346
0.403843 0.339273
0.397447 0.32984
0.401007 0.345187
0.401435 0.350856
0.404534 0.358367
0.40019 0.350997
0.401021 0.359769
0.398586 0.362409
0.403735 0.370503
0.400571 0.381428
0.409145 0.374727
0.402981 0.379619
0.406312 0.38398
0.405032 0.387826

View File

@ -0,0 +1,826 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Simple_cartesian.h>
// Graphs
#include <CGAL/Polyhedron_3.h>
#include <CGAL/IO/Polyhedron_iostream.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/boost/graph/graph_traits_Regular_triangulation_2.h>
#include <CGAL/boost/graph/properties_Regular_triangulation_2.h>
#include <CGAL/Polygon_mesh_processing/locate.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_face_graph_triangle_primitive.h>
#include <CGAL/Bbox_3.h>
#include <CGAL/boost/graph/io.h>
#include <CGAL/boost/graph/named_params_helper.h>
#include <CGAL/boost/graph/generators.h>
#include <CGAL/boost/graph/helpers.h>
#include <CGAL/Dimension.h>
#include <CGAL/Kernel_traits.h>
#include <CGAL/Origin.h>
#include <CGAL/property_map.h>
#include <CGAL/Random.h>
#include <CGAL/Unique_hash_map.h>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <boost/optional.hpp>
#include <fstream>
#include <iostream>
#include <limits>
#include <map>
#include <set>
#include <type_traits>
#include <utility>
#include <vector>
namespace PMP = CGAL::Polygon_mesh_processing;
typedef CGAL::Exact_predicates_inexact_constructions_kernel EPICK;
typedef CGAL::Exact_predicates_exact_constructions_kernel EPECK;
typedef CGAL::Simple_cartesian<typename CGAL::internal::Exact_field_selector<double>::Type> Exact_kernel;
template<typename AABB_tree>
typename CGAL::Kernel_traits<typename AABB_tree::AABB_traits::Point_3>::type::Ray_2
random_2D_ray(const AABB_tree& aabb_tree, CGAL::Random& rnd)
{
typedef typename AABB_tree::AABB_traits::Point_3 Point_3;
typedef typename CGAL::Kernel_traits<Point_3>::type Kernel;
typedef typename Kernel::FT FT;
typedef typename Kernel::Point_2 Point_2;
typedef typename Kernel::Ray_2 Ray_2;
const CGAL::Bbox_3& bbox = aabb_tree.bbox();
FT px = (bbox.xmin() == bbox.xmax()) ? bbox.xmin() : rnd.get_double(bbox.xmin(), bbox.xmax());
FT py = (bbox.ymin() == bbox.ymax()) ? bbox.ymin() : rnd.get_double(bbox.ymin(), bbox.ymax());
FT qx = (bbox.xmin() == bbox.xmax()) ? bbox.xmin() : rnd.get_double(bbox.xmin(), bbox.xmax());
FT qy = (bbox.ymin() == bbox.ymax()) ? bbox.ymin() : rnd.get_double(bbox.ymin(), bbox.ymax());
return Ray_2(Point_2(px, py), Point_2(qx, qy));
}
template<typename AABB_tree>
typename CGAL::Kernel_traits<typename AABB_tree::AABB_traits::Point_3>::type::Ray_3
random_3D_ray(const AABB_tree& aabb_tree, CGAL::Random& rnd)
{
typedef typename AABB_tree::AABB_traits::Point_3 Point_3;
typedef typename CGAL::Kernel_traits<Point_3>::type Kernel;
typedef typename Kernel::FT FT;
typedef typename Kernel::Ray_3 Ray_3;
const CGAL::Bbox_3& bbox = aabb_tree.bbox();
FT px = (bbox.xmin() == bbox.xmax()) ? bbox.xmin() : rnd.get_double(bbox.xmin(), bbox.xmax());
FT py = (bbox.ymin() == bbox.ymax()) ? bbox.ymin() : rnd.get_double(bbox.ymin(), bbox.ymax());
FT pz = (bbox.zmin() == bbox.zmax()) ? bbox.zmin() : rnd.get_double(bbox.zmin(), bbox.zmax());
FT qx = (bbox.xmin() == bbox.xmax()) ? bbox.xmin() : rnd.get_double(bbox.xmin(), bbox.xmax());
FT qy = (bbox.ymin() == bbox.ymax()) ? bbox.ymin() : rnd.get_double(bbox.ymin(), bbox.ymax());
FT qz = (bbox.zmin() == bbox.zmax()) ? bbox.zmin() : rnd.get_double(bbox.zmin(), bbox.zmax());
return Ray_3(Point_3(px, py, pz), Point_3(qx, qy, qz));
}
template<typename FT>
bool is_equal(const FT& a, const FT& b)
{
if(std::is_floating_point<FT>::value)
return (CGAL::abs(a - b) <= 1e-7); // numeric_limits' epsilon is too restrictive...
else
return (a == b);
}
template<typename G>
void test_snappers(const G& g)
{
std::cout << " test snappers..." << std::endl;
typedef typename PMP::Location_traits<G>::FT FT;
typename PMP::Location_traits<G>::Barycentric_coordinates coords = CGAL::make_array(FT(1e-6), FT(0.9999999999999999999), FT(1e-7));
typename PMP::Location_traits<G>::Face_location loc = std::make_pair(*(faces(g).first), coords);
// ---------------------------------------------------------------------------
PMP::internal::snap_coordinates_to_border<G>(coords); // uses numeric_limits' epsilon()
assert(coords[0] == FT(1e-6) && coords[1] == FT(1) && coords[2] == FT(1e-7));
PMP::internal::snap_coordinates_to_border<G>(coords, 1e-5);
assert(coords[0] == FT(0) && coords[1] == FT(1) && coords[2] == FT(0));
// ---------------------------------------------------------------------------
PMP::internal::snap_location_to_border<G>(loc); // uses numeric_limits' epsilon()
assert(!PMP::is_on_face_border(loc, g));
PMP::internal::snap_location_to_border<G>(loc, 1e-7);
assert(PMP::is_on_face_border(loc, g));
}
template <typename K, int>
struct Point_to_bare_point
{
typedef typename K::Point_2 type;
};
template <typename K>
struct Point_to_bare_point<K, 3>
{
typedef typename K::Point_3 type;
};
template<typename G>
void test_constructions(const G& g, CGAL::Random& rnd)
{
std::cout << " test constructions..." << std::endl;
typedef typename boost::graph_traits<G>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<G>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<G>::face_descriptor face_descriptor;
typedef typename PMP::Location_traits<G>::descriptor_variant descriptor_variant;
typedef typename boost::property_map_value<G, CGAL::vertex_point_t>::type Point;
typedef typename CGAL::Kernel_traits<Point>::type Kernel;
typedef typename Kernel::FT FT;
typedef typename Point_to_bare_point<Kernel, Point::Ambient_dimension::value>::type Bare_point;
typedef typename PMP::Location_traits<G>::Barycentric_coordinates Barycentric_coordinates;
typedef typename PMP::Location_traits<G>::Face_location Face_location;
typedef typename boost::property_map<G, CGAL::vertex_point_t>::const_type VPM;
VPM vpm = CGAL::get_const_property_map(boost::vertex_point, g);
face_descriptor f = CGAL::internal::random_face_in_mesh(g, rnd);
halfedge_descriptor h = halfedge(f, g);
vertex_descriptor v = source(h, g);
Point p = get(vpm, v);
Point q = get(vpm, target(h, g));
Point r = get(vpm, target(next(h, g), g));
Bare_point bp(p);
Bare_point bq(q);
Bare_point br(r);
Barycentric_coordinates bar;
Face_location loc;
loc.first = f;
// ---------------------------------------------------------------------------
bar = PMP::barycentric_coordinates(p, q, r, p, Kernel());
assert(is_equal(bar[0], FT(1)) && is_equal(bar[1], FT(0)) && is_equal(bar[2], FT(0)));
bar = PMP::barycentric_coordinates(p, q, r, q, Kernel());
assert(is_equal(bar[0], FT(0)) && is_equal(bar[1], FT(1)) && is_equal(bar[2], FT(0)));
bar = PMP::barycentric_coordinates(p, q, r, r, Kernel());
assert(is_equal(bar[0], FT(0)) && is_equal(bar[1], FT(0)) && is_equal(bar[2], FT(1)));
Point mp = Point(CGAL::midpoint(bp, bq));
bar = PMP::barycentric_coordinates(p, q, r, mp);
assert(is_equal(bar[0], FT(0.5)) && is_equal(bar[1], FT(0.5)) && is_equal(bar[2], FT(0)));
int n = 100;
while(n --> 0) // :)
{
const FT a = rnd.get_double(-1., 1.);
const FT b = rnd.get_double(-1., 1.);
const FT c = 1. - a - b;
Bare_point barycentric_pt = CGAL::barycenter(bp, a, bq, b, br, c);
bar = PMP::barycentric_coordinates(p, q, r, Point(barycentric_pt));
assert(is_equal(bar[0], a) && is_equal(bar[1], b) && is_equal(bar[2], c));
loc.second = bar;
const FT sq_dist = CGAL::squared_distance(barycentric_pt, Bare_point(PMP::construct_point(loc, g)));
assert(is_equal(sq_dist, FT(0)));
}
// ---------------------------------------------------------------------------
loc = std::make_pair(f, CGAL::make_array(FT(0.3), FT(0.4), FT(0.3)));
descriptor_variant dv = PMP::get_descriptor_from_location(loc, g);
const face_descriptor* fd = boost::get<face_descriptor>(&dv);
assert(fd);
loc = std::make_pair(f, CGAL::make_array(FT(0.5), FT(0.5), FT(0)));
dv = PMP::get_descriptor_from_location(loc, g);
const halfedge_descriptor* hd = boost::get<halfedge_descriptor>(&dv);
assert(hd);
loc = std::make_pair(f, CGAL::make_array(FT(1), FT(0), FT(0)));
assert(PMP::is_on_vertex(loc, source(halfedge(f, g), g), g));
dv = PMP::get_descriptor_from_location(loc, g);
if(const vertex_descriptor* v = boost::get<vertex_descriptor>(&dv)) { } else { assert(false); }
// ---------------------------------------------------------------------------
Point s = PMP::construct_point(loc, g, CGAL::parameters::all_default());
s = PMP::construct_point(loc, g);
assert(s == get(vpm, source(halfedge(f, g), g)));
}
template<typename G>
void test_random_entities(const G& g, CGAL::Random& rnd)
{
std::cout << " test random entities..." << std::endl;
typedef typename boost::graph_traits<G>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<G>::face_descriptor face_descriptor;
typedef typename PMP::Location_traits<G>::Face_location Face_location;
typedef typename boost::property_map_value<G, CGAL::vertex_point_t>::type Point;
typedef typename CGAL::Kernel_traits<Point>::type Kernel;
typedef typename Kernel::FT FT;
// ---------------------------------------------------------------------------
Face_location loc;
halfedge_descriptor h = CGAL::internal::random_halfedge_in_mesh(g, rnd);
if(is_border(h, g))
h = opposite(h, g);
face_descriptor f = CGAL::internal::random_face_in_mesh(g, rnd);
int nn = 100;
while(nn --> 0) // the infamous 'go to zero' operator
{
loc = PMP::random_location_on_mesh(g, rnd);
assert(loc.first != boost::graph_traits<G>::null_face());
assert(loc.second[0] >= FT(0) && loc.second[0] <= FT(1) &&
loc.second[1] >= FT(0) && loc.second[1] <= FT(1) &&
loc.second[2] >= FT(0) && loc.second[2] <= FT(1));
loc = PMP::random_location_on_face(f, g, rnd);
assert(loc.first == f);
assert(loc.second[0] >= FT(0) && loc.second[0] <= FT(1) &&
loc.second[1] >= FT(0) && loc.second[1] <= FT(1) &&
loc.second[2] >= FT(0) && loc.second[2] <= FT(1));
loc = PMP::random_location_on_halfedge(h, g, rnd);
assert(loc.first == face(h, g));
assert(loc.second[0] >= FT(0) && loc.second[0] <= FT(1) &&
loc.second[1] >= FT(0) && loc.second[1] <= FT(1) &&
loc.second[2] >= FT(0) && loc.second[2] <= FT(1));
int h_id = CGAL::halfedge_index_in_face(h, g);
assert(loc.second[(h_id+2)%3] == FT(0));
}
}
template<typename G>
void test_helpers(const G& g, CGAL::Random& rnd)
{
std::cout << " test helpers..." << std::endl;
typedef typename boost::graph_traits<G>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<G>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<G>::face_descriptor face_descriptor;
typedef typename PMP::Location_traits<G>::Face_location Face_location;
face_descriptor f = CGAL::internal::random_face_in_mesh(g, rnd);
halfedge_descriptor h = halfedge(f, g);
vertex_descriptor v = source(h, g);
// ---------------------------------------------------------------------------
// Local index
int pos = CGAL::vertex_index_in_face(v, f, g);
assert(pos == 0);
pos = CGAL::vertex_index_in_face(target(h, g), f, g);
assert(pos == 1);
pos = CGAL::vertex_index_in_face(target(next(h, g), g), f, g);
assert(pos == 2);
pos = CGAL::halfedge_index_in_face(h, g);
assert(pos == 0);
pos = CGAL::halfedge_index_in_face(next(h, g), g);
assert(pos == 1);
pos = CGAL::halfedge_index_in_face(prev(h, g), g);
assert(pos == 2);
// ---------------------------------------------------------------------------
// Incident faces
Face_location loc = PMP::random_location_on_face(f, g, rnd);
std::set<face_descriptor> s;
PMP::internal::incident_faces(loc, g, std::inserter(s, s.begin()));
assert(PMP::is_on_face_border(loc, g) || s.size() == 1);
loc = PMP::random_location_on_halfedge(h, g, rnd);
std::vector<face_descriptor> vec;
PMP::internal::incident_faces(loc, g, std::back_inserter(vec));
assert(PMP::is_on_vertex(loc, source(h, g), g) || PMP::is_on_vertex(loc, target(h, g), g) || vec.size() == 2);
}
template<typename G>
void test_predicates(const G& g, CGAL::Random& rnd)
{
std::cout << " test predicates..." << std::endl;
typedef typename boost::property_map_value<G, CGAL::vertex_point_t>::type Point;
typedef typename CGAL::Kernel_traits<Point>::type Kernel;
typedef typename Kernel::FT FT;
typedef typename boost::graph_traits<G>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<G>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<G>::face_descriptor face_descriptor;
typedef typename PMP::Location_traits<G>::Face_location Face_location;
face_descriptor f = CGAL::internal::random_face_in_mesh(g, rnd);
halfedge_descriptor h = halfedge(f, g);
vertex_descriptor v = source(h, g);
// ---------------------------------------------------------------------------
Face_location loc(f, CGAL::make_array(FT(1), FT(0), FT(0)));
assert(PMP::is_on_vertex(loc, v, g));
loc = Face_location(f, CGAL::make_array(FT(0), FT(1), FT(0)));
assert(PMP::is_on_vertex(loc, target(h, g), g));
loc = Face_location(f, CGAL::make_array(FT(0), FT(0), FT(1)));
assert(PMP::is_on_vertex(loc, target(next(h, g), g), g));
loc = Face_location(f, CGAL::make_array(FT(-1), FT(1), FT(1)));
assert(!PMP::is_on_vertex(loc, target(next(h, g), g), g));
// ---------------------------------------------------------------------------
loc = Face_location(f, CGAL::make_array(FT(0.5), FT(0.5), FT(0)));
assert(PMP::is_on_halfedge(loc, h, g));
loc = Face_location(f, CGAL::make_array(FT(0), FT(0.5), FT(0.5)));
assert(PMP::is_on_halfedge(loc, next(h, g), g));
loc = Face_location(f, CGAL::make_array(FT(-0.5), FT(1.5), FT(0)));
assert(!PMP::is_on_halfedge(loc, h, g));
loc = Face_location(f, CGAL::make_array(FT(0.1), FT(-0.6), FT(1.5)));
assert(!PMP::is_on_halfedge(loc, h, g));
// ---------------------------------------------------------------------------
loc = Face_location(f, CGAL::make_array(FT(0.3), FT(0.3), FT(0.4)));
assert(PMP::is_in_face(loc, g));
loc = Face_location(f, CGAL::make_array(FT(0), FT(0), FT(1)));
assert(PMP::is_in_face(loc, g));
loc = Face_location(f, CGAL::make_array(FT(0), FT(2), FT(-1)));
assert(!PMP::is_in_face(loc, g));
// ---------------------------------------------------------------------------
loc = Face_location(f, CGAL::make_array(FT(0.3), FT(0.3), FT(0.4)));
assert(!PMP::is_on_face_border(loc, g));
loc = Face_location(f, CGAL::make_array(FT(0), FT(0.6), FT(0.4)));
assert(PMP::is_on_face_border(loc, g));
loc = Face_location(f, CGAL::make_array(FT(0), FT(0), FT(1)));
assert(PMP::is_on_face_border(loc, g));
loc = Face_location(f, CGAL::make_array(FT(-0.2), FT(0), FT(1.2)));
assert(!PMP::is_on_face_border(loc, g));
// ---------------------------------------------------------------------------
int max = 1000, counter = 0;
typename boost::graph_traits<G>::halfedge_iterator hit, hend;
boost::tie(hit, hend) = halfedges(g);
for(; hit!=hend; ++hit)
{
const halfedge_descriptor h = *hit;
if(face(h, g) == boost::graph_traits<G>::null_face())
continue;
const int id_of_h = CGAL::halfedge_index_in_face(h, g);
const face_descriptor f = face(h, g);
loc.first = f;
loc.second[id_of_h] = FT(1);
loc.second[(id_of_h+1)%3] = FT(0);
loc.second[(id_of_h+2)%3] = FT(0);
boost::optional<halfedge_descriptor> opt_hd = CGAL::is_border(source(h, g), g);
assert(PMP::is_on_mesh_border(loc, g) == (opt_hd != boost::none));
loc.second[id_of_h] = FT(0.5);
loc.second[(id_of_h+1)%3] = FT(0.5);
assert(PMP::is_on_mesh_border(loc, g) == CGAL::is_border(edge(h, g), g));
// Even if the point does lie on the border of the mesh, 'false' is returned because
// another face descriptor should be used.
loc.second[id_of_h] = -0.5;
loc.second[(id_of_h+1)%3] = 1.5;
assert(!PMP::is_on_mesh_border(loc, g));
if(++counter > max)
break;
}
}
template<typename G>
void test_locate_in_face(const G& g, CGAL::Random& rnd)
{
std::cout << " test locate_in_face()..." << std::endl;
typedef typename boost::property_map_value<G, CGAL::vertex_point_t>::type Point;
typedef typename CGAL::Kernel_traits<Point>::type Kernel;
typedef typename Kernel::FT FT;
typedef typename boost::graph_traits<G>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<G>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<G>::face_descriptor face_descriptor;
typedef typename PMP::Location_traits<G>::Face_location Face_location;
typedef typename boost::property_map<G, CGAL::vertex_point_t>::const_type VertexPointMap;
VertexPointMap vpm = CGAL::get_const_property_map(boost::vertex_point, g);
const face_descriptor f = CGAL::internal::random_face_in_mesh(g, rnd);
const halfedge_descriptor h = halfedge(f, g);
const vertex_descriptor v = target(h, g);
Face_location loc;
typename PMP::Location_traits<G>::FT a = 0.1;
Point p = get(vpm, v);
loc = PMP::locate_in_face(v, g);
assert(is_equal(loc.second[CGAL::vertex_index_in_face(v, loc.first, g)], FT(1)));
assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g)+1)%3], FT(0)));
assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g)+2)%3], FT(0)));
loc = PMP::locate_in_face(v, f, g);
assert(loc.first == f);
assert(is_equal(loc.second[0], FT(0)) && is_equal(loc.second[1], FT(1)) && is_equal(loc.second[2], FT(0)));
loc = PMP::locate_in_face(h, a, g);
const int h_id = CGAL::halfedge_index_in_face(h, g);
assert(loc.first == f && is_equal(loc.second[(h_id+2)%3], FT(0)));
loc = PMP::locate_in_face(p, f, g, CGAL::parameters::all_default());
int v_id = CGAL::vertex_index_in_face(v, f, g);
assert(loc.first == f && is_equal(loc.second[v_id], FT(1)));
loc = PMP::locate_in_face(p, f, g);
v_id = CGAL::vertex_index_in_face(v, f, g);
assert(loc.first == f && is_equal(loc.second[v_id], FT(1)));
// ---------------------------------------------------------------------------
loc.second[0] = FT(0.2);
loc.second[1] = FT(0.8);
loc.second[2] = FT(0);
halfedge_descriptor neigh_hd = opposite(halfedge(f, g), g);
face_descriptor neigh_f = face(neigh_hd, g);
// Want to check good correspondence seen from one side and the other. If unfortunately
// we have selected a border face, can't do anything!
if(neigh_f != boost::graph_traits<G>::null_face())
{
int neigh_hd_id = CGAL::halfedge_index_in_face(neigh_hd, g);
Face_location neigh_loc;
neigh_loc.first = neigh_f;
neigh_loc.second[neigh_hd_id] = FT(0.3);
neigh_loc.second[(neigh_hd_id+1)%3] = FT(0.7);
neigh_loc.second[(neigh_hd_id+2)%3] = FT(0);
PMP::locate_in_adjacent_face(loc, neigh_f, g);
assert(PMP::locate_in_common_face(loc, neigh_loc, g));
assert(PMP::locate_in_common_face(loc, p, neigh_loc, g));
assert(PMP::locate_in_common_face(loc, p, neigh_loc, g, 1e-7));
}
}
template <int dim>
struct Locate_with_AABB_tree_Tester // 2D case
{
template <typename G>
void operator()(const G& g, CGAL::Random& rnd) const
{
std::cout << " test locate_with_AABB_tree (2D)..." << std::endl;
typedef typename boost::property_map_value<G, CGAL::vertex_point_t>::type Point;
typedef typename boost::property_map<G, CGAL::vertex_point_t>::const_type VertexPointMap;
typedef typename CGAL::Kernel_traits<Point>::type Kernel;
typedef typename Kernel::FT FT;
typedef typename Kernel::Ray_2 Ray_2;
typedef typename Kernel::Ray_3 Ray_3;
typedef typename Kernel::Point_3 Point_3;
typedef typename boost::graph_traits<G>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<G>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<G>::face_descriptor face_descriptor;
typedef typename PMP::Location_traits<G>::Face_location Face_location;
face_descriptor f = CGAL::internal::random_face_in_mesh(g, rnd);
halfedge_descriptor h = halfedge(f, g);
vertex_descriptor v = target(h, g);
// ---------------------------------------------------------------------------
typedef typename boost::property_traits<VertexPointMap>::value_type Intrinsic_point;
typedef PMP::internal::Point_to_Point_3<G, Intrinsic_point> Intrinsic_point_to_Point_3;
typedef PMP::internal::Point_to_Point_3_VPM<G, VertexPointMap> WrappedVertexPointMap;
typedef CGAL::AABB_face_graph_triangle_primitive<G, WrappedVertexPointMap> AABB_face_graph_primitive;
typedef CGAL::AABB_traits<Kernel, AABB_face_graph_primitive> AABB_face_graph_traits;
CGAL_static_assertion((std::is_same<typename AABB_face_graph_traits::Point_3, Point_3>::value));
Intrinsic_point_to_Point_3 to_p3;
CGAL::AABB_tree<AABB_face_graph_traits> tree_a;
VertexPointMap vpm_a = CGAL::get_const_property_map(boost::vertex_point, g);
typename boost::property_traits<VertexPointMap>::value_type p_a = get(vpm_a, v);
const Point_3& p3_a = to_p3(p_a);
CGAL::AABB_tree<AABB_face_graph_traits> tree_b;
WrappedVertexPointMap vpm_b(g);
// ---------------------------------------------------------------------------
PMP::build_AABB_tree(g, tree_a);
assert(tree_a.size() == num_faces(g));
PMP::build_AABB_tree(g, tree_b, CGAL::parameters::vertex_point_map(vpm_b));
assert(tree_b.size() == num_faces(g));
Face_location loc = PMP::locate_with_AABB_tree(p_a, tree_a, g);
// sanitize otherwise some test platforms fail
PMP::internal::snap_location_to_border<G>(loc, 1e-7);
assert(PMP::is_on_vertex(loc, v, g)); // might fail du to precision issues...
assert(is_equal(loc.second[CGAL::vertex_index_in_face(v, loc.first, g)], FT(1)));
assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g)+1)%3], FT(0)));
assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g)+2)%3], FT(0)));
assert(is_equal(CGAL::squared_distance(to_p3(PMP::construct_point(loc, g)), p3_a), FT(0)));
loc = PMP::locate_with_AABB_tree(p_a, tree_a, g, CGAL::parameters::vertex_point_map(vpm_a));
assert(is_equal(CGAL::squared_distance(to_p3(PMP::construct_point(loc, g)), p3_a), FT(0)));
// ---------------------------------------------------------------------------
loc = PMP::locate(p_a, g);
assert(is_equal(CGAL::squared_distance(to_p3(PMP::construct_point(loc, g)), p3_a), FT(0)));
assert(PMP::is_in_face(loc, g));
loc = PMP::locate_with_AABB_tree(CGAL::ORIGIN, tree_b, g, CGAL::parameters::vertex_point_map(vpm_b));
assert(PMP::is_in_face(loc, g));
loc = PMP::locate(CGAL::ORIGIN, g, CGAL::parameters::vertex_point_map(vpm_b));
assert(PMP::is_in_face(loc, g));
// ---------------------------------------------------------------------------
Ray_2 r2 = random_2D_ray<CGAL::AABB_tree<AABB_face_graph_traits> >(tree_a, rnd);
loc = PMP::locate_with_AABB_tree(r2, tree_a, g);
if(loc.first != boost::graph_traits<G>::null_face())
assert(PMP::is_in_face(loc, g));
Ray_3 r3 = random_3D_ray<CGAL::AABB_tree<AABB_face_graph_traits> >(tree_b, rnd);
loc = PMP::locate_with_AABB_tree(r3, tree_b, g, CGAL::parameters::vertex_point_map(vpm_b));
}
};
template <typename K>
struct My_3D_Point
{
typedef typename K::FT FT;
typedef K R;
typedef CGAL::Dimension_tag<3> Ambient_dimension;
typedef CGAL::Dimension_tag<0> Feature_dimension;
My_3D_Point() { }
My_3D_Point(const CGAL::Origin& /*o*/) : cx(0), cy(0), cz(0) { }
My_3D_Point(const FT x, const FT y, const FT z) : cx(x), cy(y), cz(z) { }
FT x() const { return cx; }
FT y() const { return cy; }
FT z() const { return cz; }
private:
FT cx, cy, cz;
};
template <>
struct Locate_with_AABB_tree_Tester<3> // 3D
{
template <typename G>
void operator()(const G& g, CGAL::Random& rnd) const
{
std::cout << " test locate_with_AABB_tree (3D)..." << std::endl;
typedef typename boost::property_map_value<G, CGAL::vertex_point_t>::type Point;
typedef typename CGAL::Kernel_traits<Point>::type Kernel;
typedef typename Kernel::FT FT;
typedef typename Kernel::Ray_3 Ray_3;
typedef typename Kernel::Point_3 Point_3;
typedef typename boost::graph_traits<G>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<G>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<G>::face_descriptor face_descriptor;
typedef typename PMP::Location_traits<G>::Face_location Face_location;
face_descriptor f = CGAL::internal::random_face_in_mesh(g, rnd);
halfedge_descriptor h = halfedge(f, g);
vertex_descriptor v = target(h, g);
// ---------------------------------------------------------------------------
typedef typename PMP::Location_traits<G>::VPM VertexPointMap;
typedef CGAL::AABB_face_graph_triangle_primitive<G, VertexPointMap> AABB_face_graph_primitive;
typedef CGAL::AABB_traits<Kernel, AABB_face_graph_primitive> AABB_face_graph_traits;
CGAL_static_assertion((std::is_same<typename AABB_face_graph_traits::Point_3, Point_3>::value));
CGAL::AABB_tree<AABB_face_graph_traits> tree_a;
VertexPointMap vpm_a = CGAL::get_const_property_map(boost::vertex_point, g);
typename boost::property_traits<VertexPointMap>::value_type p3_a = get(vpm_a, v);
// below tests the case where the value type of the VPM is not Kernel::Point_3
typedef My_3D_Point<Kernel> Intrinsic_point;
typedef std::map<vertex_descriptor, Intrinsic_point> Custom_map;
typedef boost::associative_property_map<Custom_map> Custom_VPM;
typedef PMP::internal::Point_to_Point_3_VPM<G, Custom_VPM> WrappedVertexPointMap;
typedef CGAL::AABB_face_graph_triangle_primitive<G, WrappedVertexPointMap> AABB_face_graph_primitive_with_WVPM;
typedef CGAL::AABB_traits<Kernel, AABB_face_graph_primitive_with_WVPM> AABB_face_graph_traits_with_WVPM;
CGAL::AABB_tree<AABB_face_graph_traits_with_WVPM> tree_b;
Custom_map custom_map;
for(vertex_descriptor vd : vertices(g))
{
const Point_3& p = get(vpm_a, vd);
custom_map[vd] = Intrinsic_point(p.x(), p.y(), p.z());
}
Custom_VPM custom_vpm(custom_map);
WrappedVertexPointMap vpm_b(custom_vpm);
// ---------------------------------------------------------------------------
PMP::build_AABB_tree(g, tree_a);
assert(tree_a.size() == num_faces(g));
PMP::build_AABB_tree(g, tree_b, CGAL::parameters::vertex_point_map(vpm_b));
assert(tree_b.size() == num_faces(g));
Face_location loc = PMP::locate_with_AABB_tree(p3_a, tree_a, g);
assert(is_equal(loc.second[CGAL::vertex_index_in_face(v, loc.first, g)], FT(1)));
assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g)+1)%3], FT(0)));
assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g)+2)%3], FT(0)));
assert(is_equal(CGAL::squared_distance(PMP::construct_point(loc, g), p3_a), FT(0)));
loc = PMP::locate_with_AABB_tree(p3_a, tree_a, g, CGAL::parameters::vertex_point_map(vpm_a));
assert(is_equal(CGAL::squared_distance(PMP::construct_point(loc, g), p3_a), FT(0)));
// ---------------------------------------------------------------------------
loc = PMP::locate(p3_a, g);
assert(is_equal(CGAL::squared_distance(PMP::construct_point(loc, g), p3_a), FT(0)));
assert(PMP::is_in_face(loc, g));
loc = PMP::locate_with_AABB_tree(CGAL::ORIGIN, tree_b, g, CGAL::parameters::vertex_point_map(vpm_b));
assert(PMP::is_in_face(loc, g));
// doesn't necessarily have to wrap with a P_to_P3 here, it'll do it internally
loc = PMP::locate(CGAL::ORIGIN, g, CGAL::parameters::vertex_point_map(custom_vpm));
assert(PMP::is_in_face(loc, g));
// ---------------------------------------------------------------------------
Ray_3 r3 = random_3D_ray<CGAL::AABB_tree<AABB_face_graph_traits_with_WVPM> >(tree_b, rnd);
loc = PMP::locate_with_AABB_tree(r3, tree_b, g, CGAL::parameters::vertex_point_map(vpm_b));
}
};
template<typename G>
void test_locate(const G& g, CGAL::Random& rnd)
{
assert(num_vertices(g) != 0 && num_faces(g) != 0);
test_snappers(g);
test_constructions(g, rnd);
test_random_entities(g, rnd);
test_helpers(g, rnd);
test_predicates(g, rnd);
test_locate_in_face(g, rnd);
// This test has slight syntax changes between 2D and 3D (e.g. testing ray_2 in 3D makes no sense)
Locate_with_AABB_tree_Tester<
CGAL::Ambient_dimension<typename PMP::Location_traits<G>::Point>::value>()(g, rnd);
}
template<typename K>
void test_2D_triangulation(const char* fname, CGAL::Random& rnd)
{
typedef CGAL::Regular_triangulation_2<K> RT;
std::cout << "Testing Regular_triangulation_2 " << fname;
std::ifstream in(fname);
assert(in.good());
RT tr;
double x, y;
while(in >> x >> y)
tr.insert(typename RT::Point(x, y));
std::ofstream out("triangulation.off");
out << "OFF\n";
out << tr.number_of_vertices() << " " << std::distance(tr.finite_faces_begin(), tr.finite_faces_end()) << " 0\n";
std::size_t counter = 0;
std::map<typename RT::Point_2, std::size_t> ids;
for(const auto& v : CGAL::make_range(tr.finite_vertices_begin(), tr.finite_vertices_end()))
{
out << v.point().point() << " 0\n";
if(ids.insert(std::make_pair(v.point().point(), counter)).second)
++counter;
}
for(const auto& fd : CGAL::make_range(tr.finite_faces_begin(), tr.finite_faces_end()))
{
out << "3 " << ids[fd.vertex(0)->point().point()] << " " << ids[fd.vertex(1)->point().point()] << " " << ids[fd.vertex(2)->point().point()] << "\n";
}
out.close();
std::cout << " (" << tr.number_of_vertices() << " vertices)..." << std::endl;
std::cout << "Kernel: " << typeid(K()).name() << std::endl;
test_locate(tr, rnd);
}
template<typename K>
void test_2D_surface_mesh(const char* fname, CGAL::Random& rnd)
{
typedef typename K::Point_2 Point;
typedef CGAL::Surface_mesh<Point> Mesh;
std::cout << "Testing Surface_mesh " << fname << "..." << std::endl;
std::cout << "Kernel: " << typeid(K()).name() << std::endl;
std::ifstream input(fname);
assert(input.good());
Mesh tm;
if(!input || !(input >> tm))
{
std::cerr << "Error: cannot read file.";
return;
}
test_locate(tm, rnd);
}
template<typename K>
void test_3D_surface_mesh(const char* fname, CGAL::Random& rnd)
{
typedef typename K::Point_3 Point;
typedef CGAL::Surface_mesh<Point> Mesh;
std::cout << "Testing Surface_mesh " << fname << "..." << std::endl;
std::cout << "Kernel: " << typeid(K()).name() << std::endl;
std::ifstream input(fname);
Mesh tm;
if(!input || !(input >> tm))
{
std::cerr << "Error: cannot read file.";
return;
}
test_locate(tm, rnd);
}
template<typename K>
void test_polyhedron(const char* fname, CGAL::Random& rnd)
{
typedef CGAL::Polyhedron_3<K> Polyhedron;
std::cout << "Testing Polyhedron_3 " << fname << "..." << std::endl;
std::cout << "Kernel: " << typeid(K()).name() << std::endl;
std::ifstream input(fname);
Polyhedron poly;
if(!input || !(input >> poly))
{
std::cerr << "Error: cannot read file.";
return;
}
test_locate(poly, rnd);
}
template <typename K>
void test(CGAL::Random& rnd)
{
test_2D_triangulation<K>("data/stair.xy", rnd);
test_2D_surface_mesh<K>("data/blobby_2D.off", rnd);
test_3D_surface_mesh<K>("data/mech-holes-shark.off", rnd);
test_polyhedron<K>("data-coref/elephant_split_2.off", rnd);
}
int main()
{
std::cout.precision(17);
std::cout << std::fixed;
// CGAL::Random rnd(1557332474); // if needed to debug with a fixed seed
CGAL::Random rnd(CGAL::get_default_random());
std::cout << "The seed is " << rnd.get_seed() << std::endl;
test<EPICK>(rnd);
test<Exact_kernel>(rnd);
return EXIT_SUCCESS;
}

View File

@ -9,6 +9,7 @@ Number_types
Principal_component_analysis_LGPL
Profiling_tools
Property_map
Random_numbers
Ridges_3
STL_Extension
Stream_support

View File

@ -9,6 +9,7 @@ Modular_arithmetic
Number_types
Profiling_tools
Property_map
Random_numbers
STL_Extension
Stream_support
Subdivision_method_3

View File

@ -42,6 +42,7 @@
#include <boost/cstdint.hpp>
#include <boost/array.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <CGAL/Dimension.h>
#include <CGAL/property_map.h>
#include <CGAL/Iterator_range.h>
#include <CGAL/circulator.h>
@ -257,8 +258,9 @@ namespace CGAL {
// increment.
SM_Edge_index operator++(int) { SM_Edge_index tmp(*this); halfedge_ = SM_Halfedge_index((size_type)halfedge_ + 2); return tmp; }
SM_Edge_index operator+=(std::ptrdiff_t n) { halfedge_ = SM_Halfedge_index(size_type(std::ptrdiff_t(halfedge_) + 2*n)); return *this; }
// prints the index and a short identification string to an ostream.
// prints the index and a short identification string to an ostream.
friend std::ostream& operator<<(std::ostream& os, SM_Edge_index const& e)
{
return (os << 'e' << (size_type)e << " on " << e.halfedge());
@ -2088,6 +2090,24 @@ private: //------------------------------------------------------- private data
return sm;
}
/// \cond SKIP_IN_MANUAL
template <typename Point,
int dim = CGAL::Ambient_dimension<Point>::value>
struct Output_point_23
{
template<typename Stream>
Stream& operator()(Stream& os, const Point& p) const { os << p.x() << " " << p.y() << " " << p.z(); return os; }
};
template <typename Point>
struct Output_point_23<Point, 2> // 2D Point specialization
{
template<typename Stream>
Stream& operator()(Stream& os, const Point& p) const { os << p.x() << " " << p.y(); return os; }
};
/// \endcond
/// \relates Surface_mesh
/// Inserts the surface mesh in an output stream in Ascii OFF format.
@ -2121,10 +2141,12 @@ private: //------------------------------------------------------- private data
get_const_property_map(CGAL::vertex_point, sm));
reindex.resize(sm.num_vertices());
int n = 0;
Output_point_23<P> op;
for(Vertex_index v : sm.vertices()){
P p = get(vpm, v);
os << p.x() << " " << p.y() << " " << p.z();
op(os, get(vpm, v));
if(has_vcolors)
{
CGAL::Color color = vcolors[v];
@ -2360,6 +2382,30 @@ private: //------------------------------------------------------- private data
return in;
}
template <typename Point,
int dimension = CGAL::Ambient_dimension<Point>::value>
struct Read_point_23
{
template <typename Stream>
Point operator()(Stream& is) const
{
double x, y, z;
is >> iformat(x) >> iformat(y) >> iformat(z);
return Point(x, y, z);
}
};
template <typename Point>
struct Read_point_23<Point, 2> // 2D specialization
{
template <typename Stream>
Point operator()(Stream& is) const
{
double x, y;
is >> iformat(x) >> iformat(y);
return Point(x, y);
}
};
/// @endcond
@ -2418,14 +2464,12 @@ private: //------------------------------------------------------- private data
}
char ci;
Read_point_23<P> point_reader;
for(int i=0; i < n; i++){
is >> sm_skip_comments;
double x, y, z;
is >> iformat(x) >> iformat(y) >> iformat(z);
Vertex_index vi = sm.add_vertex();
put(vpm, vi, P(x, y, z));
put(vpm, vi, point_reader(is));
vertexmap[i] = vi;
if(v_has_normals){
@ -2433,7 +2477,6 @@ private: //------------------------------------------------------- private data
vnormal[vi] = v;
}
if(i == 0 && ((off == "COFF") || (off == "CNOFF"))){
std::string col;
std::getline(is, col);

View File

@ -13,6 +13,7 @@ Modular_arithmetic
Number_types
Profiling_tools
Property_map
Random_numbers
STL_Extension
Stream_support
Surface_mesh

View File

@ -14,6 +14,7 @@ Principal_component_analysis
Principal_component_analysis_LGPL
Profiling_tools
Property_map
Random_numbers
STL_Extension
Solver_interface
Stream_support

View File

@ -14,6 +14,7 @@ Number_types
Polygon_mesh_processing
Profiling_tools
Property_map
Random_numbers
STL_Extension
Solver_interface
Stream_support

View File

@ -17,6 +17,7 @@ Polygon
Polygon_mesh_processing
Profiling_tools
Property_map
Random_numbers
STL_Extension
Solver_interface
Spatial_sorting

View File

@ -13,6 +13,7 @@ Modular_arithmetic
Number_types
Profiling_tools
Property_map
Random_numbers
STL_Extension
Spatial_searching
Stream_support

View File

@ -11,6 +11,7 @@ Modular_arithmetic
Number_types
Profiling_tools
Property_map
Random_numbers
STL_Extension
Stream_support
Surface_mesh_simplification

View File

@ -61,8 +61,7 @@ class Triangulation_data_structure_2
typedef typename Vb::template Rebind_TDS<Tds>::Other Vertex_base;
typedef typename Fb::template Rebind_TDS<Tds>::Other Face_base;
friend class Triangulation_ds_edge_iterator_2<Tds,false>;
friend class Triangulation_ds_edge_iterator_2<Tds,true>;
friend class Triangulation_ds_edge_iterator_2<Tds>;
friend class Triangulation_ds_face_circulator_2<Tds>;
friend class Triangulation_ds_edge_circulator_2<Tds>;
friend class Triangulation_ds_vertex_circulator_2<Tds>;
@ -90,9 +89,7 @@ public:
typedef typename Face_range::iterator Face_iterator;
typedef typename Vertex_range::iterator Vertex_iterator;
typedef Triangulation_ds_edge_iterator_2<Tds> Edge_iterator;
typedef Triangulation_ds_edge_iterator_2<Tds,false> Halfedge_iterator;
typedef Triangulation_ds_face_circulator_2<Tds> Face_circulator;
typedef Triangulation_ds_vertex_circulator_2<Tds> Vertex_circulator;
@ -104,8 +101,7 @@ public:
typedef Vertex_iterator Vertex_handle;
typedef Face_iterator Face_handle;
typedef std::pair<Face_handle,int> Edge;
typedef std::pair<Face_handle, int> Edge;
typedef std::list<Edge> List_edges;
@ -204,14 +200,6 @@ public:
return Edges(edges_begin(),edges_end());
}
Halfedge_iterator halfedges_begin() const {
return Halfedge_iterator(this);
}
Halfedge_iterator halfedges_end() const {
return Halfedge_iterator(this,1);
}
Face_circulator incident_faces(Vertex_handle v,
Face_handle f = Face_handle()) const{
return Face_circulator(v,f);

View File

@ -31,8 +31,7 @@
namespace CGAL {
// with Once set to false, the Edge is reported twice, seen from the two adjacentfaces
template <class Tds, bool Once = true>
template <class Tds>
class Triangulation_ds_edge_iterator_2
{
public:
@ -47,7 +46,7 @@ public:
typedef std::ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
typedef Triangulation_ds_edge_iterator_2<Tds,Once> Edge_iterator;
typedef Triangulation_ds_edge_iterator_2<Tds> Edge_iterator;
private:
const Tds* _tds;
@ -71,15 +70,14 @@ public:
private:
void increment();
void decrement();
bool associated_edge(CGAL::Tag_true);
bool associated_edge(CGAL::Tag_false);
bool associated_edge();
};
// Edge iterator implementation
template<class Tds, bool Once>
Triangulation_ds_edge_iterator_2<Tds,Once> ::
template<class Tds>
Triangulation_ds_edge_iterator_2<Tds>::
Triangulation_ds_edge_iterator_2(const Tds * tds)
: _tds(tds)
{
@ -90,12 +88,12 @@ Triangulation_ds_edge_iterator_2(const Tds * tds)
}
pos = _tds->faces().begin();
if (_tds->dimension() == 1) edge.second = 2;
while ( pos != _tds->faces().end()
&& !associated_edge(Boolean_tag<Once>()) ) increment();
while ( pos != _tds->faces().end() && !associated_edge())
increment();
}
template<class Tds, bool Once>
Triangulation_ds_edge_iterator_2<Tds,Once> ::
template<class Tds>
Triangulation_ds_edge_iterator_2<Tds>::
Triangulation_ds_edge_iterator_2(const Tds * tds, int )
: _tds(tds)
{
@ -105,19 +103,19 @@ Triangulation_ds_edge_iterator_2(const Tds * tds, int )
}
template<class Tds, bool Once>
template<class Tds>
inline
bool
Triangulation_ds_edge_iterator_2<Tds,Once> ::
Triangulation_ds_edge_iterator_2<Tds>::
operator==(const Edge_iterator& fi) const
{
return _tds == fi._tds && pos == fi.pos && edge.second == fi.edge.second;
}
template<class Tds, bool Once>
template<class Tds>
inline
void
Triangulation_ds_edge_iterator_2<Tds,Once> ::
Triangulation_ds_edge_iterator_2<Tds>::
increment()
{
CGAL_triangulation_precondition(_tds->dimension() >= 1);
@ -127,10 +125,10 @@ increment()
return;
}
template<class Tds, bool Once>
template<class Tds>
inline
void
Triangulation_ds_edge_iterator_2<Tds,Once> ::
Triangulation_ds_edge_iterator_2<Tds>::
decrement()
{
CGAL_triangulation_precondition(_tds->dimension() >= 1);
@ -140,57 +138,48 @@ decrement()
return;
}
template<class Tds, bool Once>
template<class Tds>
inline
bool
Triangulation_ds_edge_iterator_2<Tds,Once> ::
associated_edge(Tag_true)
Triangulation_ds_edge_iterator_2<Tds>::
associated_edge()
{
if (_tds->dimension() == 1) {return true;}
return Face_handle(pos) < pos->neighbor(edge.second);
}
template<class Tds, bool Once>
template<class Tds>
inline
bool
Triangulation_ds_edge_iterator_2<Tds,Once> ::
associated_edge(Tag_false)
{
return true;
}
template<class Tds, bool Once>
inline
Triangulation_ds_edge_iterator_2<Tds,Once>&
Triangulation_ds_edge_iterator_2<Tds,Once> ::
Triangulation_ds_edge_iterator_2<Tds>&
Triangulation_ds_edge_iterator_2<Tds>::
operator++()
{
//CGAL_triangulation_precondition(pos != Iterator_base() &&
// pos != _tds->faces().end());
do increment();
while( pos != _tds->faces().end() && !associated_edge(Boolean_tag<Once>()));
while( pos != _tds->faces().end() && !associated_edge());
return *this;
}
template<class Tds, bool Once>
template<class Tds>
inline
Triangulation_ds_edge_iterator_2<Tds,Once>&
Triangulation_ds_edge_iterator_2<Tds,Once> ::
Triangulation_ds_edge_iterator_2<Tds>&
Triangulation_ds_edge_iterator_2<Tds>::
operator--()
{
// CGAL_triangulation_precondition(pos != Iterator_base()
// && *this != Edge_iterator(_tds));
do decrement();
while ( !associated_edge(Boolean_tag<Once>()) && *this != Edge_iterator(_tds) );
while ( !associated_edge() && *this != Edge_iterator(_tds) );
return *this;
}
template<class Tds, bool Once>
template<class Tds>
inline
Triangulation_ds_edge_iterator_2<Tds,Once>
Triangulation_ds_edge_iterator_2<Tds,Once> ::
Triangulation_ds_edge_iterator_2<Tds>
Triangulation_ds_edge_iterator_2<Tds>::
operator++(int)
{
Edge_iterator tmp(*this);
@ -198,10 +187,10 @@ operator++(int)
return tmp;
}
template<class Tds, bool Once>
template<class Tds>
inline
Triangulation_ds_edge_iterator_2<Tds,Once>
Triangulation_ds_edge_iterator_2<Tds,Once> ::
Triangulation_ds_edge_iterator_2<Tds>
Triangulation_ds_edge_iterator_2<Tds>::
operator--(int)
{
Edge_iterator tmp(*this);
@ -209,20 +198,20 @@ operator--(int)
return tmp;
}
template<class Tds, bool Once>
template<class Tds>
inline
typename Triangulation_ds_edge_iterator_2<Tds,Once>::Edge*
Triangulation_ds_edge_iterator_2<Tds,Once> ::
typename Triangulation_ds_edge_iterator_2<Tds>::Edge*
Triangulation_ds_edge_iterator_2<Tds>::
operator->() const
{
edge.first = pos;
return &edge;
}
template<class Tds, bool Once>
template<class Tds>
inline
typename Triangulation_ds_edge_iterator_2<Tds,Once>::Edge&
Triangulation_ds_edge_iterator_2<Tds,Once> ::
typename Triangulation_ds_edge_iterator_2<Tds>::Edge&
Triangulation_ds_edge_iterator_2<Tds>::
operator*() const
{
edge.first = pos;

View File

@ -32,7 +32,8 @@ when it is built for Delaunay triangulations.
However it can be used as well for other triangulations.
\tparam Tr may be any of the \cgal triangulation classes.
\tparam Tr may be any of the \cgal triangulation classes. The vertex of the triangulation must
be a model of the concept `TriangulationHierarchyVertexBase_2`.
\cgalHeading{Types}

View File

@ -130,7 +130,6 @@ public:
typedef typename Tds::Face_iterator All_faces_iterator;
typedef typename Tds::Edge_iterator All_edges_iterator;
typedef typename Tds::Halfedge_iterator All_halfedges_iterator;
typedef typename Tds::Vertex_iterator All_vertices_iterator;
class Perturbation_order
@ -491,8 +490,6 @@ public:
All_edges_iterator all_edges_end() const;
All_edges all_edges() const;
All_halfedges_iterator all_halfedges_begin() const;
All_halfedges_iterator all_halfedges_end() const;
//for compatibility with previous versions
Face_iterator faces_begin() const {return finite_faces_begin();}
@ -3348,22 +3345,6 @@ all_edges() const
return _tds.edges();
}
template <class Gt, class Tds >
typename Triangulation_2<Gt, Tds>::All_halfedges_iterator
Triangulation_2<Gt, Tds>::
all_halfedges_begin() const
{
return _tds.halfedges_begin();
}
template <class Gt, class Tds >
typename Triangulation_2<Gt, Tds>::All_halfedges_iterator
Triangulation_2<Gt, Tds>::
all_halfedges_end() const
{
return _tds.halfedges_end();
}
template <class Gt, class Tds >
inline
typename Triangulation_2<Gt, Tds>::Face_circulator

View File

@ -0,0 +1,63 @@
// Copyright (c) 2019 GeometryFactory (France). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
//
// Author(s) : Mael Rouxel-Labbé
#ifndef CGAL_TRIANGULATION_FACE_BASE_WITH_ID_2_H
#define CGAL_TRIANGULATION_FACE_BASE_WITH_ID_2_H
#include <CGAL/Triangulation_face_base_2.h>
namespace CGAL {
template < typename GT,
typename Fb = Triangulation_face_base_2<GT> >
class Triangulation_face_base_with_id_2
: public Fb
{
public:
typedef typename Fb::Vertex_handle Vertex_handle;
typedef typename Fb::Face_handle Face_handle;
template < typename TDS2 >
struct Rebind_TDS {
typedef typename Fb::template Rebind_TDS<TDS2>::Other Fb2;
typedef Triangulation_face_base_with_id_2<GT, Fb2> Other;
};
Triangulation_face_base_with_id_2() : Fb() { }
Triangulation_face_base_with_id_2(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2)
: Fb(v0, v1, v2)
{ }
Triangulation_face_base_with_id_2(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2,
Face_handle n0, Face_handle n1, Face_handle n2)
: Fb(v0, v1, v2, n0, n1, n2)
{ }
int& id() { return _id; }
int id() const { return _id; }
private:
int _id;
};
} //namespace CGAL
#endif // CGAL_TRIANGULATION_FACE_BASE_WITH_ID_2_H

View File

@ -56,11 +56,11 @@ const int Triangulation_hierarchy_2__minsize = 20;
const int Triangulation_hierarchy_2__maxlevel = 5;
// maximal number of points is 30^5 = 24 millions !
template < class Tr_>
template <class Tr_>
class Triangulation_hierarchy_2
: public Tr_
{
public:
public:
typedef Tr_ Tr_Base;
typedef typename Tr_Base::Geom_traits Geom_traits;
typedef typename Tr_Base::size_type size_type;
@ -273,8 +273,8 @@ private:
template <class Tr >
Triangulation_hierarchy_2<Tr>::
template <class Tr_>
Triangulation_hierarchy_2<Tr_>::
Triangulation_hierarchy_2(const Geom_traits& traits)
: Tr_Base(traits)
{
@ -285,9 +285,9 @@ Triangulation_hierarchy_2(const Geom_traits& traits)
// copy constructor duplicates vertices and faces
template <class Tr>
Triangulation_hierarchy_2<Tr>::
Triangulation_hierarchy_2(const Triangulation_hierarchy_2<Tr> &tr)
template <class Tr_>
Triangulation_hierarchy_2<Tr_>::
Triangulation_hierarchy_2(const Triangulation_hierarchy_2<Tr_> &tr)
: Tr_Base()
{
// create an empty triangulation to be able to delete it !
@ -299,20 +299,20 @@ Triangulation_hierarchy_2(const Triangulation_hierarchy_2<Tr> &tr)
//Assignement
template <class Tr>
Triangulation_hierarchy_2<Tr> &
Triangulation_hierarchy_2<Tr>::
operator=(const Triangulation_hierarchy_2<Tr> &tr)
template <class Tr_>
Triangulation_hierarchy_2<Tr_> &
Triangulation_hierarchy_2<Tr_>::
operator=(const Triangulation_hierarchy_2<Tr_> &tr)
{
copy_triangulation(tr);
return *this;
}
template <class Tr>
template <class Tr_>
void
Triangulation_hierarchy_2<Tr>::
copy_triangulation(const Triangulation_hierarchy_2<Tr> &tr)
Triangulation_hierarchy_2<Tr_>::
copy_triangulation(const Triangulation_hierarchy_2<Tr_> &tr)
{
{
for(int i=0;i<Triangulation_hierarchy_2__maxlevel;++i)
@ -348,18 +348,18 @@ copy_triangulation(const Triangulation_hierarchy_2<Tr> &tr)
}
}
/* template <class Tr> */
/* template <class Tr_> */
/* void */
/* Triangulation_hierarchy_2<Tr>:: */
/* Triangulation_hierarchy_2<Tr_>:: */
/* add_hidden_vertices_into_map(Tag_false, */
/* std::map<Vertex_handle,Vertex_handle >& V) { */
/* return; */
/* } */
/* template <class Tr> */
/* template <class Tr_> */
/* void */
/* Triangulation_hierarchy_2<Tr>:: */
/* Triangulation_hierarchy_2<Tr_>:: */
/* add_hidden_vertices_into_map(Tag_true, */
/* std::map<Vertex_handle,Vertex_handle >& V) */
/* { */
@ -371,10 +371,10 @@ copy_triangulation(const Triangulation_hierarchy_2<Tr> &tr)
/* } */
template <class Tr>
template <class Tr_>
void
Triangulation_hierarchy_2<Tr>::
swap(Triangulation_hierarchy_2<Tr> &tr)
Triangulation_hierarchy_2<Tr_>::
swap(Triangulation_hierarchy_2<Tr_> &tr)
{
Tr_Base* temp;
Tr_Base::swap(tr);
@ -385,8 +385,8 @@ swap(Triangulation_hierarchy_2<Tr> &tr)
}
}
template <class Tr>
Triangulation_hierarchy_2<Tr>::
template <class Tr_>
Triangulation_hierarchy_2<Tr_>::
~Triangulation_hierarchy_2()
{
clear();
@ -395,9 +395,9 @@ Triangulation_hierarchy_2<Tr>::
}
}
template <class Tr>
template <class Tr_>
void
Triangulation_hierarchy_2<Tr>::
Triangulation_hierarchy_2<Tr_>::
clear()
{
for(int i=0;i<Triangulation_hierarchy_2__maxlevel;++i)
@ -405,9 +405,9 @@ clear()
}
template <class Tr>
template <class Tr_>
bool
Triangulation_hierarchy_2<Tr>::
Triangulation_hierarchy_2<Tr_>::
is_valid(bool verbose, int level) const
{
bool result = true;
@ -440,9 +440,9 @@ is_valid(bool verbose, int level) const
}
template <class Tr>
typename Triangulation_hierarchy_2<Tr>::Vertex_handle
Triangulation_hierarchy_2<Tr>::
template <class Tr_>
typename Triangulation_hierarchy_2<Tr_>::Vertex_handle
Triangulation_hierarchy_2<Tr_>::
insert(const Point &p, Face_handle loc)
{
int vertex_level = random_level();
@ -466,9 +466,9 @@ insert(const Point &p, Face_handle loc)
return first;
}
template <class Tr>
typename Triangulation_hierarchy_2<Tr>::Vertex_handle
Triangulation_hierarchy_2<Tr>::
template <class Tr_>
typename Triangulation_hierarchy_2<Tr_>::Vertex_handle
Triangulation_hierarchy_2<Tr_>::
insert(const Point& p,
Locate_type lt,
Face_handle loc,
@ -499,18 +499,18 @@ insert(const Point& p,
return first;
}
template <class Tr>
template <class Tr_>
inline
typename Triangulation_hierarchy_2<Tr>::Vertex_handle
Triangulation_hierarchy_2<Tr>::
typename Triangulation_hierarchy_2<Tr_>::Vertex_handle
Triangulation_hierarchy_2<Tr_>::
push_back(const Point &p)
{
return insert(p);
}
template <class Tr>
template <class Tr_>
void
Triangulation_hierarchy_2<Tr>::
Triangulation_hierarchy_2<Tr_>::
remove(Vertex_handle v )
{
Vertex_handle u=v->up();
@ -523,10 +523,10 @@ remove(Vertex_handle v )
}
}
template <class Tr>
template <class Tr_>
template <class OutputItFaces>
void
Triangulation_hierarchy_2<Tr>::
Triangulation_hierarchy_2<Tr_>::
remove_and_give_new_faces(Vertex_handle v, OutputItFaces fit)
{
Vertex_handle u=v->up();
@ -541,33 +541,33 @@ remove_and_give_new_faces(Vertex_handle v, OutputItFaces fit)
}
template <class Tr>
template <class Tr_>
inline void
Triangulation_hierarchy_2<Tr>::
Triangulation_hierarchy_2<Tr_>::
remove_degree_3(Vertex_handle v )
{
remove(v);
}
template <class Tr>
template <class Tr_>
inline void
Triangulation_hierarchy_2<Tr>::
Triangulation_hierarchy_2<Tr_>::
remove_first(Vertex_handle v )
{
remove(v);
}
template <class Tr>
template <class Tr_>
inline void
Triangulation_hierarchy_2<Tr>::
Triangulation_hierarchy_2<Tr_>::
remove_second(Vertex_handle v )
{
remove(v);
}
template <class Tr>
typename Triangulation_hierarchy_2<Tr>::Vertex_handle
Triangulation_hierarchy_2<Tr>::
template <class Tr_>
typename Triangulation_hierarchy_2<Tr_>::Vertex_handle
Triangulation_hierarchy_2<Tr_>::
move_if_no_collision(Vertex_handle v, const Point &p) {
Vertex_handle u=v->up(), norm = v;
int l = 0 ;
@ -581,9 +581,9 @@ move_if_no_collision(Vertex_handle v, const Point &p) {
return norm;
}
template <class Tr>
typename Triangulation_hierarchy_2<Tr>::Vertex_handle
Triangulation_hierarchy_2<Tr>::
template <class Tr_>
typename Triangulation_hierarchy_2<Tr_>::Vertex_handle
Triangulation_hierarchy_2<Tr_>::
move(Vertex_handle v, const Point &p) {
CGAL_triangulation_precondition(!is_infinite(v));
Vertex_handle w = move_if_no_collision(v,p);
@ -594,10 +594,10 @@ move(Vertex_handle v, const Point &p) {
return v;
}
template <class Tr>
template <class Tr_>
template <class OutputItFaces>
typename Triangulation_hierarchy_2<Tr>::Vertex_handle
Triangulation_hierarchy_2<Tr>::
typename Triangulation_hierarchy_2<Tr_>::Vertex_handle
Triangulation_hierarchy_2<Tr_>::
move_if_no_collision_and_give_new_faces(Vertex_handle v, const Point &p,
OutputItFaces oif)
{
@ -619,11 +619,11 @@ move_if_no_collision_and_give_new_faces(Vertex_handle v, const Point &p,
return norm;
}
template < class Tr >
template <class Tr_>
template < class OutputItFaces >
inline
typename Triangulation_hierarchy_2<Tr>::Vertex_handle
Triangulation_hierarchy_2<Tr>::insert_and_give_new_faces(const Point &p,
typename Triangulation_hierarchy_2<Tr_>::Vertex_handle
Triangulation_hierarchy_2<Tr_>::insert_and_give_new_faces(const Point &p,
OutputItFaces oif,
Face_handle loc)
{
@ -649,11 +649,11 @@ Triangulation_hierarchy_2<Tr>::insert_and_give_new_faces(const Point &p,
return first;
}
template < class Tr >
template <class Tr_>
template < class OutputItFaces >
inline
typename Triangulation_hierarchy_2<Tr>::Vertex_handle
Triangulation_hierarchy_2<Tr>::
typename Triangulation_hierarchy_2<Tr_>::Vertex_handle
Triangulation_hierarchy_2<Tr_>::
insert_and_give_new_faces(const Point &p,
Locate_type lt,
Face_handle loc,
@ -685,9 +685,9 @@ insert_and_give_new_faces(const Point &p,
return first;
}
template <class Tr>
typename Triangulation_hierarchy_2<Tr>::Face_handle
Triangulation_hierarchy_2<Tr>::
template <class Tr_>
typename Triangulation_hierarchy_2<Tr_>::Face_handle
Triangulation_hierarchy_2<Tr_>::
locate(const Point& p, Locate_type& lt, int& li, Face_handle loc) const
{
Face_handle positions[Triangulation_hierarchy_2__maxlevel];
@ -695,9 +695,9 @@ locate(const Point& p, Locate_type& lt, int& li, Face_handle loc) const
return positions[0];
}
template <class Tr>
typename Triangulation_hierarchy_2<Tr>::Face_handle
Triangulation_hierarchy_2<Tr>::
template <class Tr_>
typename Triangulation_hierarchy_2<Tr_>::Face_handle
Triangulation_hierarchy_2<Tr_>::
locate(const Point& p, Face_handle loc ) const
{
Locate_type lt;
@ -705,9 +705,9 @@ locate(const Point& p, Face_handle loc ) const
return locate(p, lt, li, loc);
}
template <class Tr>
template <class Tr_>
void
Triangulation_hierarchy_2<Tr>::
Triangulation_hierarchy_2<Tr_>::
locate_in_all(const Point& p,
Locate_type& lt,
int& li,
@ -769,9 +769,9 @@ locate_in_all(const Point& p,
pos[0]=hierarchy[0]->locate(p,lt,li,loc == Face_handle() ? position : loc); // at level 0
}
template <class Tr>
template <class Tr_>
int
Triangulation_hierarchy_2<Tr>::
Triangulation_hierarchy_2<Tr_>::
random_level()
{
boost::geometric_distribution<> proba(1.0/Triangulation_hierarchy_2__ratio);

View File

@ -21,185 +21,17 @@
#ifndef CGAL_GRAPH_TRAITS_CONSTRAINED_DELAUNAY_TRIANGULATION_2_H
#define CGAL_GRAPH_TRAITS_CONSTRAINED_DELAUNAY_TRIANGULATION_2_H
// include this to avoid a VC15 warning
#include <CGAL/boost/graph/named_function_params.h>
#include <boost/config.hpp>
#include <boost/iterator_adaptors.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <CGAL/boost/graph/graph_traits_Constrained_triangulation_2.h>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
#include <CGAL/boost/graph/properties_Constrained_Delaunay_triangulation_2.h>
// The functions and classes in this file allows the user to
// treat a CGAL Constrained_triangulation_2 object as a boost graph "as is". No
// wrapper is needed for the Constrained_triangulation_2 object.
// treat a CGAL Delaunay_triangulation_2 object as a boost graph "as is". No
// wrapper is needed for the Constrained_Delaunay_triangulation_2 object.
#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS, typename Itag
#define CGAL_2D_TRIANGULATION CGAL::Constrained_Delaunay_triangulation_2<GT, TDS, Itag>
#define CGAL_2D_TRIANGULATION_TEMPLATES GT, TDS, Itag
namespace boost {
template <class GT, class TDS, class ITAG>
struct graph_traits< CGAL::Constrained_Delaunay_triangulation_2<GT,TDS,ITAG> > {
struct DT2_graph_traversal_category :
public virtual bidirectional_graph_tag,
public virtual adjacency_graph_tag,
public virtual edge_list_graph_tag,
public virtual vertex_list_graph_tag { };
typedef CGAL::Constrained_Delaunay_triangulation_2<GT,TDS,ITAG> Constrained_Delaunay_triangulation;
typedef typename CGAL::Constrained_Delaunay_triangulation_2<GT,TDS,ITAG>::Vertex_handle vertex_descriptor;
typedef typename CGAL::Constrained_Delaunay_triangulation_2<GT,TDS,ITAG>::Face_handle face_descriptor;
typedef CGAL::detail::Edge<CGAL::Constrained_Delaunay_triangulation_2<GT,TDS,ITAG>, typename CGAL::Constrained_Delaunay_triangulation_2<GT,TDS,ITAG>::Edge> edge_descriptor;
typedef typename CGAL::Constrained_Delaunay_triangulation_2<GT,TDS,ITAG>::All_edges_iterator edge_iterator;
typedef CGAL::detail::T2_halfedge_descriptor<typename Constrained_Delaunay_triangulation::Triangulation> halfedge_descriptor;
typedef typename Constrained_Delaunay_triangulation::All_halfedges_iterator halfedge_iterator;
typedef CGAL::Prevent_deref<typename Constrained_Delaunay_triangulation::All_vertices_iterator> vertex_iterator;
typedef CGAL::Prevent_deref<typename Constrained_Delaunay_triangulation::All_faces_iterator> face_iterator;
typedef CGAL::Counting_iterator<CGAL::detail::Out_edge_circulator<typename Constrained_Delaunay_triangulation::Edge_circulator, edge_descriptor>, edge_descriptor > out_edge_iterator;
typedef CGAL::Counting_iterator<CGAL::detail::In_edge_circulator<typename Constrained_Delaunay_triangulation::Edge_circulator, edge_descriptor>, edge_descriptor > in_edge_iterator;
typedef CGAL::Counting_iterator<typename Constrained_Delaunay_triangulation::Vertex_circulator> Incident_vertices_iterator;
typedef Incident_vertices_iterator adjacency_iterator;
typedef undirected_tag directed_category;
typedef disallow_parallel_edge_tag edge_parallel_category;
typedef DT2_graph_traversal_category traversal_category;
typedef typename Constrained_Delaunay_triangulation::size_type size_type;
typedef size_type vertices_size_type;
typedef size_type edges_size_type;
typedef size_type halfedges_size_type;
typedef size_type faces_size_type;
typedef size_type degree_size_type;
// nulls
static vertex_descriptor null_vertex() { return vertex_descriptor(); }
static face_descriptor null_face() { return face_descriptor(); }
static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); }
};
} // namespace boost
namespace CGAL {
template <class Gt, class Tds, class ITAG>
typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG> >::vertex_descriptor
source(typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG> >::edge_descriptor e,
const CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG>& g)
{
return e.first->vertex(g.ccw(e.second));
}
template <class Gt, class Tds, class ITAG>
typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG> >::vertex_descriptor
target(typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG> >::edge_descriptor e,
const CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG>& g)
{
return e.first->vertex(g.cw(e.second));
}
template <class Gt, class Tds, class ITAG>
inline std::pair<
typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG> >::out_edge_iterator,
typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG> >::out_edge_iterator >
out_edges(
typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG> >::vertex_descriptor u,
const CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG>& g)
{
typename CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG>::Edge_circulator ec(u,u->face());
typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG> >::degree_size_type out_deg = out_degree(u,g);
typedef typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG> >
::out_edge_iterator Iter;
return std::make_pair( Iter(ec), Iter(ec,out_deg) );
}
template <class Gt, class Tds, class ITAG>
inline std::pair<
typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG> >::in_edge_iterator,
typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG> >::in_edge_iterator >
in_edges(
typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG> >::vertex_descriptor u,
const CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG>& g)
{
typename CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG>::Edge_circulator ec(u,u->face());
typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG> >::degree_size_type out_deg = out_degree(u,g);
typedef typename boost::graph_traits< CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG> >
::in_edge_iterator Iter;
return std::make_pair( Iter(ec), Iter(ec,out_deg) );
}
template <class Gt, class Tds, class ITAG>
inline CT2_vertex_id_map<Gt,Tds,ITAG>
get(boost::vertex_index_t, const CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG>& ) {
CT2_vertex_id_map<Gt,Tds,ITAG> m;
return m;
}
template <class Gt, class Tds, class ITAG>
inline CT2_vertex_point_map<Gt,Tds,ITAG>
get(boost::vertex_point_t, const CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG>& ) {
CT2_vertex_point_map<Gt,Tds,ITAG> m;
return m;
}
template <class Gt, class Tds, class ITAG>
inline CT2_edge_id_map<Gt,Tds,ITAG>
get(boost::edge_index_t, const CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG>& ) {
CT2_edge_id_map<Gt,Tds,ITAG> m;
return m;
}
template <class Gt, class Tds, class ITAG>
inline CT2_edge_weight_map<Gt,Tds,ITAG>
get(boost::edge_weight_t, const CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG>& g) {
CT2_edge_weight_map<Gt,Tds,ITAG> m(g);
return m;
}
} // namespace CGAL
namespace boost {
// g++ 'enumeral_type' in template unification not implemented workaround
template <class Gt, class Tds, class ITAG, class Tag>
struct property_map<CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG>, Tag> {
typedef typename
CGAL::CT2_property_map<Tag>::template bind_<Gt,Tds,ITAG> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
// see struct property_map in Polyehdron for an explanation
template <class Gt, class Tds, class ITAG, class Tag>
struct property_map<const CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG>, Tag> {
typedef typename
CGAL::CT2_property_map<Tag>::template bind_<Gt,Tds,ITAG> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
// What are those needed for ???
template <typename Gt, typename Tds, typename ITAG>
struct edge_property_type<CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG> > {
typedef void type;
};
template <typename Gt, typename Tds, typename ITAG>
struct vertex_property_type<CGAL::Constrained_Delaunay_triangulation_2<Gt,Tds,ITAG> > {
typedef void type;
};
} // namespace boost
#include <CGAL/boost/graph/internal/graph_traits_2D_triangulation.h>
#endif // CGAL_GRAPH_TRAITS_CONSTRAINED_DELAUNAY_TRIANGULATION_2_H

View File

@ -21,309 +21,17 @@
#ifndef CGAL_GRAPH_TRAITS_CONSTRAINED_TRIANGULATION_2_H
#define CGAL_GRAPH_TRAITS_CONSTRAINED_TRIANGULATION_2_H
// include this to avoid a VC15 warning
#include <CGAL/boost/graph/named_function_params.h>
#include <boost/config.hpp>
#include <boost/iterator_adaptors.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <CGAL/boost/graph/graph_traits_Triangulation_2.h>
#include <CGAL/Constrained_triangulation_2.h>
#include <CGAL/boost/graph/properties_Constrained_triangulation_2.h>
// The functions and classes in this file allows the user to
// treat a CGAL Constrained_triangulation_2 object as a boost graph "as is". No
// treat a CGAL Delaunay_triangulation_2 object as a boost graph "as is". No
// wrapper is needed for the Constrained_triangulation_2 object.
#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS, typename Itag
#define CGAL_2D_TRIANGULATION CGAL::Constrained_triangulation_2<GT, TDS, Itag>
#define CGAL_2D_TRIANGULATION_TEMPLATES GT, TDS, Itag
namespace boost {
template <class GT, class TDS, class ITAG>
struct graph_traits< CGAL::Constrained_triangulation_2<GT,TDS,ITAG> > {
struct DT2_graph_traversal_category :
public virtual bidirectional_graph_tag,
public virtual adjacency_graph_tag,
public virtual edge_list_graph_tag,
public virtual vertex_list_graph_tag { };
typedef CGAL::Constrained_triangulation_2<GT,TDS,ITAG> Constrained_triangulation;
typedef typename CGAL::Constrained_triangulation_2<GT,TDS,ITAG>::Vertex_handle vertex_descriptor;
typedef typename CGAL::Constrained_triangulation_2<GT,TDS,ITAG>::Face_handle face_descriptor;
typedef CGAL::detail::Edge<CGAL::Constrained_triangulation_2<GT,TDS,ITAG>, typename CGAL::Constrained_triangulation_2<GT,TDS,ITAG>::Edge> edge_descriptor;
typedef typename CGAL::Constrained_triangulation_2<GT,TDS,ITAG>::All_edges_iterator edge_iterator;
typedef CGAL::detail::T2_halfedge_descriptor<typename Constrained_triangulation::Triangulation> halfedge_descriptor;
typedef typename Constrained_triangulation::All_halfedges_iterator halfedge_iterator;
typedef CGAL::Prevent_deref<typename Constrained_triangulation::All_vertices_iterator> vertex_iterator;
typedef CGAL::Prevent_deref<typename Constrained_triangulation::All_faces_iterator> face_iterator;
typedef CGAL::Counting_iterator<CGAL::detail::Out_edge_circulator<typename Constrained_triangulation::Edge_circulator, edge_descriptor>, edge_descriptor > out_edge_iterator;
typedef CGAL::Counting_iterator<CGAL::detail::In_edge_circulator<typename Constrained_triangulation::Edge_circulator, edge_descriptor>, edge_descriptor > in_edge_iterator;
typedef CGAL::Counting_iterator<typename Constrained_triangulation::Vertex_circulator> Incident_vertices_iterator;
typedef Incident_vertices_iterator adjacency_iterator;
typedef undirected_tag directed_category;
typedef disallow_parallel_edge_tag edge_parallel_category;
typedef DT2_graph_traversal_category traversal_category;
typedef typename Constrained_triangulation::size_type size_type;
typedef size_type vertices_size_type;
typedef size_type edges_size_type;
typedef size_type halfedges_size_type;
typedef size_type faces_size_type;
typedef size_type degree_size_type;
// nulls
static vertex_descriptor null_vertex() { return vertex_descriptor(); }
static face_descriptor null_face() { return face_descriptor(); }
static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); }
};
} // namespace boost
namespace CGAL {
template <class Gt, class Tds, class ITAG>
typename boost::graph_traits< CGAL::Constrained_triangulation_2<Gt,Tds,ITAG> >::vertex_descriptor
source(typename boost::graph_traits< CGAL::Constrained_triangulation_2<Gt,Tds,ITAG> >::edge_descriptor e,
const CGAL::Constrained_triangulation_2<Gt,Tds,ITAG>& g)
{
return e.first->vertex(g.ccw(e.second));
}
template <class Gt, class Tds, class ITAG>
typename boost::graph_traits< CGAL::Constrained_triangulation_2<Gt,Tds,ITAG> >::vertex_descriptor
target(typename boost::graph_traits< CGAL::Constrained_triangulation_2<Gt,Tds,ITAG> >::edge_descriptor e,
const CGAL::Constrained_triangulation_2<Gt,Tds,ITAG>& g)
{
return e.first->vertex(g.cw(e.second));
}
template <class Gt, class Tds, class ITAG>
inline std::pair<
typename boost::graph_traits< CGAL::Constrained_triangulation_2<Gt,Tds,ITAG> >::out_edge_iterator,
typename boost::graph_traits< CGAL::Constrained_triangulation_2<Gt,Tds,ITAG> >::out_edge_iterator >
out_edges(
typename boost::graph_traits< CGAL::Constrained_triangulation_2<Gt,Tds,ITAG> >::vertex_descriptor u,
const CGAL::Constrained_triangulation_2<Gt,Tds,ITAG>& g)
{
typename CGAL::Constrained_triangulation_2<Gt,Tds,ITAG>::Edge_circulator ec(u,u->face());
typename boost::graph_traits< CGAL::Constrained_triangulation_2<Gt,Tds,ITAG> >::degree_size_type out_deg = out_degree(u,g);
typedef typename boost::graph_traits< CGAL::Constrained_triangulation_2<Gt,Tds,ITAG> >
::out_edge_iterator Iter;
return std::make_pair( Iter(ec), Iter(ec,out_deg) );
}
template <class Gt, class Tds, class ITAG>
inline std::pair<
typename boost::graph_traits< CGAL::Constrained_triangulation_2<Gt,Tds,ITAG> >::in_edge_iterator,
typename boost::graph_traits< CGAL::Constrained_triangulation_2<Gt,Tds,ITAG> >::in_edge_iterator >
in_edges(
typename boost::graph_traits< CGAL::Constrained_triangulation_2<Gt,Tds,ITAG> >::vertex_descriptor u,
const CGAL::Constrained_triangulation_2<Gt,Tds,ITAG>& g)
{
typename CGAL::Constrained_triangulation_2<Gt,Tds,ITAG>::Edge_circulator ec(u,u->face());
typename boost::graph_traits< CGAL::Constrained_triangulation_2<Gt,Tds,ITAG> >::degree_size_type out_deg = out_degree(u,g);
typedef typename boost::graph_traits< CGAL::Constrained_triangulation_2<Gt,Tds,ITAG> >
::in_edge_iterator Iter;
return std::make_pair( Iter(ec), Iter(ec,out_deg) );
}
// property maps
template <class Gt, class Tds, class ITAG>
class CT2_vertex_id_map
: public boost::put_get_helper<int, CT2_vertex_id_map<Gt,Tds,ITAG> >
{
public:
typedef boost::readable_property_map_tag category;
typedef int value_type;
typedef int reference;
typedef typename CGAL::Constrained_triangulation_2<Gt,Tds,ITAG>::Vertex_handle key_type;
CT2_vertex_id_map()
{}
long operator[](key_type vh) const {
return vh->id();
}
};
template <class Gt, class Tds, class ITAG>
class CT2_vertex_point_map
{
public:
typedef boost::lvalue_property_map_tag category;
typedef typename CGAL::Constrained_triangulation_2<Gt,Tds,ITAG>::Point value_type;
typedef value_type& reference;
typedef typename CGAL::Constrained_triangulation_2<Gt,Tds,ITAG>::Vertex_handle key_type;
friend reference get(CT2_vertex_point_map<Gt,Tds,ITAG>, key_type vh)
{
return vh->point();
}
friend void put(CT2_vertex_point_map<Gt,Tds,ITAG>, key_type vh, reference v)
{
vh->point()=v;
}
reference operator[](key_type vh) const {
return vh->point();
}
};
template <class Gt, class Tds, class ITAG>
class CT2_edge_id_map
: public boost::put_get_helper<int, CT2_edge_id_map<Gt,Tds,ITAG> >
{
public:
typedef boost::readable_property_map_tag category;
typedef int value_type;
typedef int reference;
typedef typename CGAL::Constrained_triangulation_2<Gt,Tds,ITAG>::Edge key_type;
CT2_edge_id_map()
{}
long operator[](key_type e) const {
return (3 * e.first.id()) + e.second;
}
};
template <class Gt, class Tds, class ITAG>
class CT2_edge_weight_map
: public boost::put_get_helper<typename Gt::FT, CT2_edge_weight_map<Gt, Tds,ITAG> >
{
private:
const CGAL::Constrained_triangulation_2<Gt,Tds,ITAG>& tr;
public:
typedef boost::readable_property_map_tag category;
typedef typename Gt::FT value_type;
typedef value_type reference;
typedef typename CGAL::Constrained_triangulation_2<Gt,Tds,ITAG>::Edge key_type;
CT2_edge_weight_map(const CGAL::Constrained_triangulation_2<Gt,Tds,ITAG>& tr_)
: tr(tr_)
{ }
typename Gt::FT operator[](key_type e) const {
return approximate_sqrt(tr.segment(e).squared_length());
}
};
template <class Gt, class Tds, class ITAG>
inline CT2_vertex_id_map<Gt,Tds,ITAG>
get(boost::vertex_index_t, const CGAL::Constrained_triangulation_2<Gt,Tds,ITAG>& ) {
CT2_vertex_id_map<Gt,Tds,ITAG> m;
return m;
}
template <class Gt, class Tds, class ITAG>
inline CT2_vertex_point_map<Gt,Tds,ITAG>
get(boost::vertex_point_t, const CGAL::Constrained_triangulation_2<Gt,Tds,ITAG>& ) {
CT2_vertex_point_map<Gt,Tds,ITAG> m;
return m;
}
template <class Gt, class Tds, class ITAG>
inline CT2_edge_id_map<Gt,Tds,ITAG>
get(boost::edge_index_t, const CGAL::Constrained_triangulation_2<Gt,Tds,ITAG>& ) {
CT2_edge_id_map<Gt,Tds,ITAG> m;
return m;
}
template <class Gt, class Tds, class ITAG>
inline CT2_edge_weight_map<Gt,Tds,ITAG>
get(boost::edge_weight_t, const CGAL::Constrained_triangulation_2<Gt,Tds,ITAG>& g) {
CT2_edge_weight_map<Gt,Tds,ITAG> m(g);
return m;
}
template <class Tag>
struct CT2_property_map { };
template <>
struct CT2_property_map<boost::vertex_index_t> {
template <class Gt, class Tds, class ITAG>
struct bind_ {
typedef CT2_vertex_id_map<Gt,Tds,ITAG> type;
typedef CT2_vertex_id_map<Gt,Tds,ITAG> const_type;
};
};
template <>
struct CT2_property_map<boost::vertex_point_t> {
template <class Gt, class Tds, class ITAG>
struct bind_ {
typedef CT2_vertex_point_map<Gt,Tds,ITAG> type;
typedef CT2_vertex_point_map<Gt,Tds,ITAG> const_type;
};
};
template <>
struct CT2_property_map<boost::edge_index_t> {
template <class Gt, class Tds, class ITAG>
struct bind_ {
typedef CT2_edge_id_map<Gt,Tds,ITAG> type;
typedef CT2_edge_id_map<Gt,Tds,ITAG> const_type;
};
};
template <>
struct CT2_property_map<boost::edge_weight_t> {
template <class Gt, class Tds, class ITAG>
struct bind_ {
typedef CT2_edge_weight_map<Gt,Tds,ITAG> type;
typedef CT2_edge_weight_map<Gt,Tds,ITAG> const_type;
};
};
} // namespace CGAL
namespace boost {
// g++ 'enumeral_type' in template unification not implemented workaround
template <class Gt, class Tds, class ITAG, class Tag>
struct property_map<CGAL::Constrained_triangulation_2<Gt,Tds,ITAG>, Tag> {
typedef typename
CGAL::CT2_property_map<Tag>::template bind_<Gt,Tds,ITAG> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
// see struct property_map in Polyehdron for an explanation
template <class Gt, class Tds, class ITAG, class Tag>
struct property_map<const CGAL::Constrained_triangulation_2<Gt,Tds,ITAG>, Tag> {
typedef typename
CGAL::CT2_property_map<Tag>::template bind_<Gt,Tds,ITAG> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
// What are those needed for ???
template <typename Gt, typename Tds, typename ITAG>
struct edge_property_type<CGAL::Constrained_triangulation_2<Gt,Tds,ITAG> > {
typedef void type;
};
template <typename Gt, typename Tds, typename ITAG>
struct vertex_property_type<CGAL::Constrained_triangulation_2<Gt,Tds,ITAG> > {
typedef void type;
};
} // namespace boost
#include <CGAL/boost/graph/internal/graph_traits_2D_triangulation.h>
#endif // CGAL_GRAPH_TRAITS_CONSTRAINED_TRIANGULATION_2_H

View File

@ -21,304 +21,17 @@
#ifndef CGAL_GRAPH_TRAITS_CONSTRAINED_TRIANGULATION_PLUS_2_H
#define CGAL_GRAPH_TRAITS_CONSTRAINED_TRIANGULATION_PLUS_2_H
// include this to avoid a VC15 warning
#include <CGAL/boost/graph/named_function_params.h>
#include <boost/config.hpp>
#include <boost/iterator_adaptors.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <CGAL/boost/graph/graph_traits_Constrained_triangulation_2.h>
#include <CGAL/Constrained_triangulation_plus_2.h>
#include <CGAL/boost/graph/properties_Constrained_triangulation_plus_2.h>
// The functions and classes in this file allows the user to
// treat a CGAL Constrained_triangulation_plus_2 object as a boost graph "as is". No
// treat a CGAL Delaunay_triangulation_2 object as a boost graph "as is". No
// wrapper is needed for the Constrained_triangulation_plus_2 object.
#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename Tr
#define CGAL_2D_TRIANGULATION CGAL::Constrained_triangulation_plus_2<Tr>
#define CGAL_2D_TRIANGULATION_TEMPLATES Tr
namespace boost {
template <class Tr>
struct graph_traits< CGAL::Constrained_triangulation_plus_2<Tr> > {
struct DT2_graph_traversal_category :
public virtual bidirectional_graph_tag,
public virtual adjacency_graph_tag,
public virtual edge_list_graph_tag,
public virtual vertex_list_graph_tag { };
typedef typename boost::graph_traits<Tr>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<Tr>::face_descriptor face_descriptor;
typedef typename boost::graph_traits<Tr>::edge_descriptor edge_descriptor;
typedef typename boost::graph_traits<Tr>::edge_iterator edge_iterator;
typedef typename boost::graph_traits<Tr>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<Tr>::halfedge_iterator halfedge_iterator;
typedef typename boost::graph_traits<Tr>::vertex_iterator vertex_iterator;
typedef typename boost::graph_traits<Tr>::face_iterator face_iterator;
typedef typename boost::graph_traits<Tr>::out_edge_iterator out_edge_iterator;
typedef typename boost::graph_traits<Tr>::in_edge_iterator in_edge_iterator;
typedef typename boost::graph_traits<Tr>::Incident_vertices_iterator Incident_vertices_iterator;
typedef undirected_tag directed_category;
typedef disallow_parallel_edge_tag edge_parallel_category;
typedef DT2_graph_traversal_category traversal_category;
typedef typename boost::graph_traits<Tr>::size_type size_type;
typedef size_type vertices_size_type;
typedef size_type edges_size_type;
typedef size_type halfedges_size_type;
typedef size_type faces_size_type;
typedef size_type degree_size_type;
// nulls
static vertex_descriptor null_vertex() { return vertex_descriptor(); }
static face_descriptor null_face() { return face_descriptor(); }
static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); }
};
} // namespace boost
namespace CGAL {
template <class Tr>
typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2<Tr> >::vertex_descriptor
source(typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2<Tr> >::edge_descriptor e,
const CGAL::Constrained_triangulation_plus_2<Tr>& g)
{
return e.first->vertex(g.ccw(e.second));
}
template <class Tr>
typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2<Tr> >::vertex_descriptor
target(typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2<Tr> >::edge_descriptor e,
const CGAL::Constrained_triangulation_plus_2<Tr>& g)
{
return e.first->vertex(g.cw(e.second));
}
template <class Tr>
inline std::pair<
typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2<Tr> >::out_edge_iterator,
typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2<Tr> >::out_edge_iterator >
out_edges(
typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2<Tr> >::vertex_descriptor u,
const CGAL::Constrained_triangulation_plus_2<Tr>& g)
{
typename CGAL::Constrained_triangulation_plus_2<Tr>::Edge_circulator ec(u,u->face());
typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2<Tr> >::degree_size_type out_deg = out_degree(u,g);
typedef typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2<Tr> >
::out_edge_iterator Iter;
return std::make_pair( Iter(ec), Iter(ec,out_deg) );
}
template <class Tr>
inline std::pair<
typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2<Tr> >::in_edge_iterator,
typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2<Tr> >::in_edge_iterator >
in_edges(
typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2<Tr> >::vertex_descriptor u,
const CGAL::Constrained_triangulation_plus_2<Tr>& g)
{
typename CGAL::Constrained_triangulation_plus_2<Tr>::Edge_circulator ec(u,u->face());
typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2<Tr> >::degree_size_type out_deg = out_degree(u,g);
typedef typename boost::graph_traits< CGAL::Constrained_triangulation_plus_2<Tr> >
::in_edge_iterator Iter;
return std::make_pair( Iter(ec), Iter(ec,out_deg) );
}
// property maps
template <class Tr>
class CTP2_vertex_id_map
: public boost::put_get_helper<int, CTP2_vertex_id_map<Tr> >
{
public:
typedef boost::readable_property_map_tag category;
typedef int value_type;
typedef int reference;
typedef typename CGAL::Constrained_triangulation_plus_2<Tr>::Vertex_handle key_type;
CTP2_vertex_id_map()
{}
long operator[](key_type vh) const {
return vh->id();
}
};
template <class Tr>
class CTP2_vertex_point_map
{
public:
typedef boost::lvalue_property_map_tag category;
typedef typename CGAL::Constrained_triangulation_plus_2<Tr>::Point value_type;
typedef value_type& reference;
typedef typename CGAL::Constrained_triangulation_plus_2<Tr>::Vertex_handle key_type;
friend reference get(CTP2_vertex_point_map<Tr>, key_type vh)
{
return vh->point();
}
friend void put(CTP2_vertex_point_map<Tr>, key_type vh, reference v)
{
vh->point()=v;
}
reference operator[](key_type vh) const {
return vh->point();
}
};
template <class Tr>
class CTP2_edge_id_map
: public boost::put_get_helper<int, CTP2_edge_id_map<Tr> >
{
public:
typedef boost::readable_property_map_tag category;
typedef int value_type;
typedef int reference;
typedef typename CGAL::Constrained_triangulation_plus_2<Tr>::Edge key_type;
CTP2_edge_id_map()
{}
long operator[](key_type e) const {
return (3 * e.first.id()) + e.second;
}
};
template <class Tr>
class CTP2_edge_weight_map
: public boost::put_get_helper<typename Tr::Geom_traits::FT, CTP2_edge_weight_map<Tr> >
{
private:
const CGAL::Constrained_triangulation_plus_2<Tr>& tr;
public:
typedef boost::readable_property_map_tag category;
typedef typename Tr::Geom_traits::FT value_type;
typedef value_type reference;
typedef typename CGAL::Constrained_triangulation_plus_2<Tr>::Edge key_type;
CTP2_edge_weight_map(const CGAL::Constrained_triangulation_plus_2<Tr>& tr_)
: tr(tr_)
{ }
typename Tr::Geom_traits::FT operator[](key_type e) const {
return approximate_sqrt(tr.segment(e).squared_length());
}
};
template <class Tr>
inline CTP2_vertex_id_map<Tr>
get(boost::vertex_index_t, const CGAL::Constrained_triangulation_plus_2<Tr>& ) {
CTP2_vertex_id_map<Tr> m;
return m;
}
template <class Tr>
inline CTP2_vertex_point_map<Tr>
get(boost::vertex_point_t, const CGAL::Constrained_triangulation_plus_2<Tr>& ) {
CTP2_vertex_point_map<Tr> m;
return m;
}
template <class Tr>
inline CTP2_edge_id_map<Tr>
get(boost::edge_index_t, const CGAL::Constrained_triangulation_plus_2<Tr>& ) {
CTP2_edge_id_map<Tr> m;
return m;
}
template <class Tr>
inline CTP2_edge_weight_map<Tr>
get(boost::edge_weight_t, const CGAL::Constrained_triangulation_plus_2<Tr>& g) {
CTP2_edge_weight_map<Tr> m(g);
return m;
}
template <class Tag>
struct CTP2_property_map { };
template <>
struct CTP2_property_map<boost::vertex_index_t> {
template <class Tr>
struct bind_ {
typedef CTP2_vertex_id_map<Tr> type;
typedef CTP2_vertex_id_map<Tr> const_type;
};
};
template <>
struct CTP2_property_map<boost::vertex_point_t> {
template <class Tr>
struct bind_ {
typedef CTP2_vertex_point_map<Tr> type;
typedef CTP2_vertex_point_map<Tr> const_type;
};
};
template <>
struct CTP2_property_map<boost::edge_index_t> {
template <class Tr>
struct bind_ {
typedef CTP2_edge_id_map<Tr> type;
typedef CTP2_edge_id_map<Tr> const_type;
};
};
template <>
struct CTP2_property_map<boost::edge_weight_t> {
template <class Tr>
struct bind_ {
typedef CTP2_edge_weight_map<Tr> type;
typedef CTP2_edge_weight_map<Tr> const_type;
};
};
} // namespace CGAL
namespace boost {
// g++ 'enumeral_type' in template unification not implemented workaround
template <class Tr, class Tag>
struct property_map<CGAL::Constrained_triangulation_plus_2<Tr>, Tag> {
typedef typename
CGAL::CTP2_property_map<Tag>::template bind_<Tr> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
// see struct property_map in Polyhedron for an explanation
template <class Tr, class Tag>
struct property_map<const CGAL::Constrained_triangulation_plus_2<Tr>, Tag> {
typedef typename
CGAL::CTP2_property_map<Tag>::template bind_<Tr> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
// What are those needed for ???
template <typename Tr>
struct edge_property_type<CGAL::Constrained_triangulation_plus_2<Tr> > {
typedef void type;
};
template <typename Tr>
struct vertex_property_type<CGAL::Constrained_triangulation_plus_2<Tr> > {
typedef void type;
};
} // namespace boost
#include <CGAL/boost/graph/internal/graph_traits_2D_triangulation.h>
#endif // CGAL_GRAPH_TRAITS_CONSTRAINED_TRIANGULATION_PLUS_2_H

View File

@ -21,156 +21,17 @@
#ifndef CGAL_GRAPH_TRAITS_DELAUNAY_TRIANGULATION_2_H
#define CGAL_GRAPH_TRAITS_DELAUNAY_TRIANGULATION_2_H
// include this to avoid a VC15 warning
#include <CGAL/boost/graph/named_function_params.h>
#include <boost/config.hpp>
#include <boost/iterator_adaptors.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <CGAL/boost/graph/graph_traits_Triangulation_2.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <CGAL/boost/graph/properties_Delaunay_triangulation_2.h>
// The functions and classes in this file allows the user to
// treat a CGAL Delaunay_triangulation_2 object as a boost graph "as is". No
// wrapper is needed for the Delaunay_triangulation_2 object.
#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS
#define CGAL_2D_TRIANGULATION CGAL::Delaunay_triangulation_2<GT, TDS>
#define CGAL_2D_TRIANGULATION_TEMPLATES GT, TDS
namespace boost {
template <class GT, class TDS>
struct graph_traits< CGAL::Delaunay_triangulation_2<GT,TDS> > {
struct DT2_graph_traversal_category :
public virtual bidirectional_graph_tag,
public virtual adjacency_graph_tag,
public virtual edge_list_graph_tag,
public virtual vertex_list_graph_tag { };
typedef CGAL::Delaunay_triangulation_2<GT,TDS> Delaunay_triangulation;
typedef typename CGAL::Delaunay_triangulation_2<GT,TDS>::Vertex_handle vertex_descriptor;
typedef typename CGAL::Triangulation_2<GT,TDS>::Face_handle face_descriptor;
typedef CGAL::detail::Edge<CGAL::Delaunay_triangulation_2<GT,TDS>, typename CGAL::Delaunay_triangulation_2<GT,TDS>::Edge> edge_descriptor;
typedef typename CGAL::Delaunay_triangulation_2<GT,TDS>::All_edges_iterator edge_iterator;
typedef CGAL::detail::T2_halfedge_descriptor<typename Delaunay_triangulation::Triangulation> halfedge_descriptor;
typedef typename Delaunay_triangulation::All_halfedges_iterator halfedge_iterator;
typedef CGAL::Prevent_deref<typename Delaunay_triangulation::All_vertices_iterator> vertex_iterator;
typedef CGAL::Prevent_deref<typename Delaunay_triangulation::All_faces_iterator> face_iterator;
typedef CGAL::Counting_iterator<CGAL::detail::Out_edge_circulator<typename Delaunay_triangulation::Edge_circulator, edge_descriptor>, edge_descriptor > out_edge_iterator;
typedef CGAL::Counting_iterator<CGAL::detail::In_edge_circulator<typename Delaunay_triangulation::Edge_circulator, edge_descriptor>, edge_descriptor > in_edge_iterator;
typedef CGAL::Counting_iterator<typename Delaunay_triangulation::Vertex_circulator> Incident_vertices_iterator;
typedef Incident_vertices_iterator adjacency_iterator;
typedef undirected_tag directed_category;
typedef disallow_parallel_edge_tag edge_parallel_category;
typedef DT2_graph_traversal_category traversal_category;
typedef typename Delaunay_triangulation::size_type size_type;
typedef size_type vertices_size_type;
typedef size_type halfedges_size_type;
typedef size_type edges_size_type;
typedef size_type faces_size_type;
typedef size_type degree_size_type;
// nulls
static vertex_descriptor null_vertex() { return vertex_descriptor(); }
static face_descriptor null_face() { return face_descriptor(); }
static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); }
};
} // namespace boost
namespace CGAL {
template <class Gt, class Tds>
typename boost::graph_traits< CGAL::Delaunay_triangulation_2<Gt,Tds> >::vertex_descriptor
source(typename boost::graph_traits< CGAL::Delaunay_triangulation_2<Gt,Tds> >::edge_descriptor e,
const CGAL::Delaunay_triangulation_2<Gt,Tds>& g)
{
return e.first->vertex(g.ccw(e.second));
}
template <class Gt, class Tds>
typename boost::graph_traits< CGAL::Delaunay_triangulation_2<Gt,Tds> >::vertex_descriptor
target(typename boost::graph_traits< CGAL::Delaunay_triangulation_2<Gt,Tds> >::edge_descriptor e,
const CGAL::Delaunay_triangulation_2<Gt,Tds>& g)
{
return e.first->vertex(g.cw(e.second));
}
template <class Gt, class Tds>
inline std::pair<
typename boost::graph_traits< CGAL::Delaunay_triangulation_2<Gt,Tds> >::out_edge_iterator,
typename boost::graph_traits< CGAL::Delaunay_triangulation_2<Gt,Tds> >::out_edge_iterator >
out_edges(
typename boost::graph_traits< CGAL::Delaunay_triangulation_2<Gt,Tds> >::vertex_descriptor u,
const CGAL::Delaunay_triangulation_2<Gt,Tds>& g)
{
typename CGAL::Delaunay_triangulation_2<Gt,Tds>::Edge_circulator ec(u,u->face());
typename boost::graph_traits< CGAL::Delaunay_triangulation_2<Gt,Tds> >::degree_size_type out_deg = out_degree(u,g);
typedef typename boost::graph_traits< CGAL::Delaunay_triangulation_2<Gt,Tds> >
::out_edge_iterator Iter;
return std::make_pair( Iter(ec), Iter(ec,out_deg) );
}
template <class Gt, class Tds>
inline std::pair<
typename boost::graph_traits< CGAL::Delaunay_triangulation_2<Gt,Tds> >::in_edge_iterator,
typename boost::graph_traits< CGAL::Delaunay_triangulation_2<Gt,Tds> >::in_edge_iterator >
in_edges(
typename boost::graph_traits< CGAL::Delaunay_triangulation_2<Gt,Tds> >::vertex_descriptor u,
const CGAL::Delaunay_triangulation_2<Gt,Tds>& g)
{
typename CGAL::Delaunay_triangulation_2<Gt,Tds>::Edge_circulator ec(u,u->face());
typename boost::graph_traits< CGAL::Delaunay_triangulation_2<Gt,Tds> >::degree_size_type out_deg = out_degree(u,g);
typedef typename boost::graph_traits< CGAL::Delaunay_triangulation_2<Gt,Tds> >
::in_edge_iterator Iter;
return std::make_pair( Iter(ec), Iter(ec,out_deg) );
}
} // namespace CGAL
namespace boost {
// g++ 'enumeral_type' in template unification not implemented workaround
template <class Gt, class Tds, class Tag>
struct property_map<CGAL::Delaunay_triangulation_2<Gt,Tds>, Tag> {
typedef typename
CGAL::T2_property_map<Tag>::template bind_<Gt,Tds> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
// see struct property_map in Polyhedron for an explanation
template <class Gt, class Tds, class Tag>
struct property_map<const CGAL::Delaunay_triangulation_2<Gt,Tds>, Tag> {
typedef typename
CGAL::T2_property_map<Tag>::template bind_<Gt,Tds> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
// What are those needed for ???
template <typename Gt, typename Tds>
struct edge_property_type<CGAL::Delaunay_triangulation_2<Gt,Tds> > {
typedef void type;
};
template <typename Gt, typename Tds>
struct vertex_property_type<CGAL::Delaunay_triangulation_2<Gt,Tds> > {
typedef void type;
};
} // namespace boost
#include <CGAL/boost/graph/internal/graph_traits_2D_triangulation.h>
#endif // CGAL_GRAPH_TRAITS_DELAUNAY_TRIANGULATION_2_H

View File

@ -21,300 +21,17 @@
#ifndef CGAL_GRAPH_TRAITS_REGULAR_TRIANGULATION_2_H
#define CGAL_GRAPH_TRAITS_REGULAR_TRIANGULATION_2_H
// include this to avoid a VC15 warning
#include <CGAL/boost/graph/named_function_params.h>
#include <boost/config.hpp>
#include <boost/iterator_adaptors.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <CGAL/boost/graph/graph_traits_Triangulation_2.h>
#include <CGAL/Regular_triangulation_2.h>
#include <CGAL/boost/graph/properties_Regular_triangulation_2.h>
// The functions and classes in this file allows the user to
// treat a CGAL Regular_triangulation_2 object as a boost graph "as is". No
// wrapper is needed for the Regular_triangulation_2 object.
#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS
#define CGAL_2D_TRIANGULATION CGAL::Regular_triangulation_2<GT, TDS>
#define CGAL_2D_TRIANGULATION_TEMPLATES GT, TDS
namespace boost {
template <class GT, class TDS>
struct graph_traits< CGAL::Regular_triangulation_2<GT,TDS> > {
struct DT2_graph_traversal_category :
public virtual bidirectional_graph_tag,
public virtual adjacency_graph_tag,
public virtual edge_list_graph_tag,
public virtual vertex_list_graph_tag { };
typedef CGAL::Regular_triangulation_2<GT,TDS> Regular_triangulation;
typedef typename CGAL::Regular_triangulation_2<GT,TDS>::Vertex_handle vertex_descriptor;
typedef typename CGAL::Triangulation_2<GT,TDS>::Face_handle face_descriptor;
typedef CGAL::detail::Edge<CGAL::Regular_triangulation_2<GT,TDS>, typename CGAL::Regular_triangulation_2<GT,TDS>::Edge> edge_descriptor;
typedef typename CGAL::Regular_triangulation_2<GT,TDS>::All_edges_iterator edge_iterator;
typedef CGAL::detail::T2_halfedge_descriptor<typename Regular_triangulation::Triangulation_base> halfedge_descriptor;
typedef typename Regular_triangulation::All_halfedges_iterator halfedge_iterator;
typedef CGAL::Prevent_deref<typename Regular_triangulation::All_vertices_iterator> vertex_iterator;
typedef CGAL::Prevent_deref<typename Regular_triangulation::All_faces_iterator> face_iterator;
typedef CGAL::Counting_iterator<CGAL::detail::Out_edge_circulator<typename Regular_triangulation::Edge_circulator, edge_descriptor>, edge_descriptor > out_edge_iterator;
typedef CGAL::Counting_iterator<CGAL::detail::In_edge_circulator<typename Regular_triangulation::Edge_circulator, edge_descriptor>, edge_descriptor > in_edge_iterator;
typedef CGAL::Counting_iterator<typename Regular_triangulation::Vertex_circulator> Incident_vertices_iterator;
typedef Incident_vertices_iterator adjacency_iterator;
typedef undirected_tag directed_category;
typedef disallow_parallel_edge_tag edge_parallel_category;
typedef DT2_graph_traversal_category traversal_category;
typedef typename Regular_triangulation::size_type size_type;
typedef size_type vertices_size_type;
typedef size_type edges_size_type;
typedef size_type halfedges_size_type;
typedef size_type faces_size_type;
typedef size_type degree_size_type;
// nulls
static vertex_descriptor null_vertex() { return vertex_descriptor(); }
static face_descriptor null_face() { return face_descriptor(); }
static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); }
};
} // namespace boost
namespace CGAL {
template <class Gt, class Tds>
inline Iterator_range<typename boost::graph_traits< Regular_triangulation_2<Gt,Tds> >::vertex_iterator>
vertices(const Regular_triangulation_2<Gt,Tds>& g)
{
typedef typename boost::graph_traits< Regular_triangulation_2<Gt,Tds> >::vertex_iterator
Iter;
return make_range( Iter(g.all_vertices_begin()), Iter(g.all_vertices_end()) );
}
template <class Gt, class Tds>
typename boost::graph_traits< CGAL::Regular_triangulation_2<Gt,Tds> >::vertex_descriptor
source(typename boost::graph_traits< CGAL::Regular_triangulation_2<Gt,Tds> >::edge_descriptor e,
const CGAL::Regular_triangulation_2<Gt,Tds>& g)
{
return e.first->vertex(g.ccw(e.second));
}
template <class Gt, class Tds>
typename boost::graph_traits< CGAL::Regular_triangulation_2<Gt,Tds> >::vertex_descriptor
target(typename boost::graph_traits< CGAL::Regular_triangulation_2<Gt,Tds> >::edge_descriptor e,
const CGAL::Regular_triangulation_2<Gt,Tds>& g)
{
return e.first->vertex(g.cw(e.second));
}
template <class Gt, class Tds>
inline std::pair<
typename boost::graph_traits< CGAL::Regular_triangulation_2<Gt,Tds> >::out_edge_iterator,
typename boost::graph_traits< CGAL::Regular_triangulation_2<Gt,Tds> >::out_edge_iterator >
out_edges(
typename boost::graph_traits< CGAL::Regular_triangulation_2<Gt,Tds> >::vertex_descriptor u,
const CGAL::Regular_triangulation_2<Gt,Tds>& g)
{
typename CGAL::Regular_triangulation_2<Gt,Tds>::Edge_circulator ec(u,u->face());
typename boost::graph_traits< CGAL::Regular_triangulation_2<Gt,Tds> >::degree_size_type out_deg = out_degree(u,g);
typedef typename boost::graph_traits< CGAL::Regular_triangulation_2<Gt,Tds> >
::out_edge_iterator Iter;
return std::make_pair( Iter(ec), Iter(ec,out_deg) );
}
template <class Gt, class Tds>
inline std::pair<
typename boost::graph_traits< CGAL::Regular_triangulation_2<Gt,Tds> >::in_edge_iterator,
typename boost::graph_traits< CGAL::Regular_triangulation_2<Gt,Tds> >::in_edge_iterator >
in_edges(
typename boost::graph_traits< CGAL::Regular_triangulation_2<Gt,Tds> >::vertex_descriptor u,
const CGAL::Regular_triangulation_2<Gt,Tds>& g)
{
typename CGAL::Regular_triangulation_2<Gt,Tds>::Edge_circulator ec(u,u->face());
typename boost::graph_traits< CGAL::Regular_triangulation_2<Gt,Tds> >::degree_size_type out_deg = out_degree(u,g);
typedef typename boost::graph_traits< CGAL::Regular_triangulation_2<Gt,Tds> >
::in_edge_iterator Iter;
return std::make_pair( Iter(ec), Iter(ec,out_deg) );
}
// property maps
template <class Gt, class Tds>
class RT2_vertex_id_map
: public boost::put_get_helper<int, RT2_vertex_id_map<Gt,Tds> >
{
public:
typedef boost::readable_property_map_tag category;
typedef int value_type;
typedef int reference;
typedef typename CGAL::Regular_triangulation_2<Gt,Tds>::Vertex_handle key_type;
RT2_vertex_id_map()
{}
long operator[](key_type vh) const {
return vh->id();
}
};
template <class Gt, class Tds>
class RT2_vertex_point_map
{
public:
typedef boost::lvalue_property_map_tag category;
typedef typename Tds::Vertex::Point value_type;
typedef value_type& reference;
typedef typename CGAL::Regular_triangulation_2<Gt,Tds>::Vertex_handle key_type;
friend reference get(RT2_vertex_point_map<Gt,Tds>, key_type vh)
{
return vh->point();
}
friend void put(RT2_vertex_point_map<Gt,Tds>, key_type vh, reference v)
{
vh->point()=v;
}
reference operator[](key_type vh) const {
return vh->point();
}
};
template <class Gt, class Tds>
class RT2_edge_id_map
: public boost::put_get_helper<int, RT2_edge_id_map<Gt,Tds> >
{
public:
typedef boost::readable_property_map_tag category;
typedef int value_type;
typedef int reference;
typedef typename CGAL::Regular_triangulation_2<Gt,Tds>::Edge key_type;
RT2_edge_id_map()
{}
long operator[](key_type e) const {
return (3 * e.first.id()) + e.second;
}
};
template <class Gt, class Tds>
class RT2_edge_weight_map
: public boost::put_get_helper<typename Gt::FT, RT2_edge_weight_map<Gt, Tds> >
{
private:
const CGAL::Regular_triangulation_2<Gt,Tds>& tr;
public:
typedef boost::readable_property_map_tag category;
typedef typename Gt::FT value_type;
typedef value_type reference;
typedef typename CGAL::Regular_triangulation_2<Gt,Tds>::Edge key_type;
RT2_edge_weight_map(const CGAL::Regular_triangulation_2<Gt,Tds>& tr_)
: tr(tr_)
{ }
value_type operator[](key_type e) const {
return approximate_sqrt(tr.segment(e).squared_length());
}
};
template <class Gt, class Tds>
inline RT2_edge_weight_map<Gt,Tds>
get(boost::edge_weight_t, const CGAL::Regular_triangulation_2<Gt,Tds>& g) {
RT2_edge_weight_map<Gt,Tds> m(g);
return m;
}
template <class Tag>
struct RT2_property_map { };
template <>
struct RT2_property_map<boost::vertex_index_t> {
template <class Gt, class Tds>
struct bind_ {
typedef RT2_vertex_id_map<Gt,Tds> type;
typedef RT2_vertex_id_map<Gt,Tds> const_type;
};
};
template <>
struct RT2_property_map<boost::vertex_point_t> {
template <class Gt, class Tds>
struct bind_ {
typedef RT2_vertex_point_map<Gt,Tds> type;
typedef RT2_vertex_point_map<Gt,Tds> const_type;
};
};
template <>
struct RT2_property_map<boost::edge_index_t> {
template <class Gt, class Tds>
struct bind_ {
typedef RT2_edge_id_map<Gt,Tds> type;
typedef RT2_edge_id_map<Gt,Tds> const_type;
};
};
template <>
struct RT2_property_map<boost::edge_weight_t> {
template <class Gt, class Tds>
struct bind_ {
typedef RT2_edge_weight_map<Gt,Tds> type;
typedef RT2_edge_weight_map<Gt,Tds> const_type;
};
};
} // namespace CGAL
namespace boost {
// g++ 'enumeral_type' in template unification not implemented workaround
template <class Gt, class Tds, class Tag>
struct property_map<CGAL::Regular_triangulation_2<Gt,Tds>, Tag> {
typedef typename
CGAL::RT2_property_map<Tag>::template bind_<Gt,Tds> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
// see struct property_map in Polyhedron for an explanation
template <class Gt, class Tds, class Tag>
struct property_map<const CGAL::Regular_triangulation_2<Gt,Tds>, Tag> {
typedef typename
CGAL::RT2_property_map<Tag>::template bind_<Gt,Tds> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
// What are those needed for ???
template <typename Gt, typename Tds>
struct edge_property_type<CGAL::Regular_triangulation_2<Gt,Tds> > {
typedef void type;
};
template <typename Gt, typename Tds>
struct vertex_property_type<CGAL::Regular_triangulation_2<Gt,Tds> > {
typedef void type;
};
} // namespace boost
#include <CGAL/boost/graph/internal/graph_traits_2D_triangulation.h>
#endif // CGAL_GRAPH_TRAITS_REGULAR_TRIANGULATION_2_H

View File

@ -21,676 +21,17 @@
#ifndef CGAL_GRAPH_TRAITS_TRIANGULATION_2_H
#define CGAL_GRAPH_TRAITS_TRIANGULATION_2_H
#include <functional>
// include this to avoid a VC15 warning
#include <CGAL/boost/graph/named_function_params.h>
#include <CGAL/boost/graph/graph_traits_Triangulation_data_structure_2.h>
#include <boost/config.hpp>
#include <boost/iterator_adaptors.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <CGAL/boost/graph/properties.h>
#include <CGAL/Triangulation_2.h>
#include <CGAL/Iterator_range.h>
#include <CGAL/iterator.h>
#include <CGAL/boost/graph/properties_Triangulation_2.h>
// The functions and classes in this file allows the user to
// treat a CGAL Triangulation_2 object as a boost graph "as is". No
// wrapper is needed for the Triangulation_2 object.
#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS
#define CGAL_2D_TRIANGULATION CGAL::Triangulation_2<GT, TDS>
#define CGAL_2D_TRIANGULATION_TEMPLATES GT, TDS
namespace CGAL {
namespace detail {
template <typename Tr>
struct T2_halfedge_descriptor
{
typedef typename Tr::Face_handle face_descriptor;
face_descriptor first;
int second;
operator std::pair<face_descriptor, int>() { return std::make_pair(first,second); }
T2_halfedge_descriptor()
: first(), second(0)
{}
T2_halfedge_descriptor(const typename Tr::Edge& e)
: first(e.first), second(e.second)
{}
T2_halfedge_descriptor(face_descriptor fd, int i)
: first(fd), second(i)
{}
friend std::size_t hash_value(const T2_halfedge_descriptor& h)
{
return hash_value(h.first);
}
bool operator==(const T2_halfedge_descriptor& other) const
{
return (first == other.first) && (second == other.second);
}
bool operator!=(const T2_halfedge_descriptor& other) const
{
return (first != other.first) || (second != other.second);
}
bool operator<(const T2_halfedge_descriptor& other) const
{
if(first < other.first) return true;
if(first > other.first) return false;
return second < other.second;
}
};
} // namespace detail
} // namespace CGAL
namespace boost {
template <class GT, class TDS>
struct graph_traits< CGAL::Triangulation_2<GT,TDS> > {
struct T2_graph_traversal_category :
public virtual bidirectional_graph_tag,
public virtual adjacency_graph_tag,
public virtual edge_list_graph_tag,
public virtual vertex_list_graph_tag { };
typedef CGAL::Triangulation_2<GT,TDS> Triangulation;
typedef typename CGAL::Triangulation_2<GT,TDS>::Vertex_handle vertex_descriptor;
typedef typename CGAL::Triangulation_2<GT,TDS>::Face_handle face_descriptor;
typedef CGAL::detail::Edge<CGAL::Triangulation_2<GT,TDS>, typename CGAL::Triangulation_2<GT,TDS>::Edge> edge_descriptor;
typedef typename CGAL::Triangulation_2<GT,TDS>::All_edges_iterator edge_iterator;
typedef CGAL::detail::T2_halfedge_descriptor<Triangulation> halfedge_descriptor;
typedef typename Triangulation::All_halfedges_iterator halfedge_iterator;
typedef CGAL::Prevent_deref<typename Triangulation::All_vertices_iterator> vertex_iterator;
typedef CGAL::Prevent_deref<typename Triangulation::All_faces_iterator> face_iterator;
typedef CGAL::Counting_iterator<CGAL::detail::Out_edge_circulator<typename Triangulation::Edge_circulator, edge_descriptor>, edge_descriptor > out_edge_iterator;
typedef CGAL::Counting_iterator<CGAL::detail::In_edge_circulator<typename Triangulation::Edge_circulator, edge_descriptor>, edge_descriptor > in_edge_iterator;
typedef CGAL::Counting_iterator<typename Triangulation::Vertex_circulator> Incident_vertices_iterator;
typedef Incident_vertices_iterator adjacency_iterator;
typedef undirected_tag directed_category;
typedef disallow_parallel_edge_tag edge_parallel_category;
typedef T2_graph_traversal_category traversal_category;
typedef typename Triangulation::size_type size_type;
typedef size_type vertices_size_type;
typedef size_type edges_size_type;
typedef size_type halfedges_size_type;
typedef size_type faces_size_type;
typedef size_type degree_size_type;
// nulls
static vertex_descriptor null_vertex() { return vertex_descriptor(); }
static face_descriptor null_face() { return face_descriptor(); }
static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); }
};
} // namespace boost
namespace CGAL {
template <class Gt, class Tds>
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::halfedge_descriptor
next(typename boost::graph_traits< Triangulation_2<Gt,Tds> >::halfedge_descriptor e,
const Triangulation_2<Gt,Tds>& g)
{
typedef typename boost::graph_traits< Triangulation_2<Gt,Tds> >::halfedge_descriptor halfedge_descriptor;
return halfedge_descriptor(e.first, g.ccw(e.second));
}
template <class Gt, class Tds>
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::halfedge_descriptor
prev(typename boost::graph_traits< Triangulation_2<Gt,Tds> >::halfedge_descriptor e,
const Triangulation_2<Gt,Tds>& g)
{
typedef typename boost::graph_traits< Triangulation_2<Gt,Tds> >::halfedge_descriptor halfedge_descriptor;
return halfedge_descriptor(e.first, g.cw(e.second));
}
template <class Gt, class Tds>
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::halfedge_descriptor
opposite(typename boost::graph_traits< Triangulation_2<Gt,Tds> >::halfedge_descriptor e,
const Triangulation_2<Gt,Tds>& g)
{
return g.mirror_edge(e);
}
template <class Gt, class Tds>
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::vertex_descriptor
source(typename boost::graph_traits< Triangulation_2<Gt,Tds> >::edge_descriptor e,
const Triangulation_2<Gt,Tds>& g)
{
return e.first->vertex(g.ccw(e.second));
}
template <class Gt, class Tds>
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::vertex_descriptor
target(typename boost::graph_traits< Triangulation_2<Gt,Tds> >::edge_descriptor e,
const Triangulation_2<Gt,Tds>& g)
{
return e.first->vertex(g.cw(e.second));
}
template <class Gt, class Tds>
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::vertex_descriptor
source(typename boost::graph_traits< Triangulation_2<Gt,Tds> >::halfedge_descriptor e,
const Triangulation_2<Gt,Tds>& g)
{
return e.first->vertex(g.ccw(e.second));
}
template <class Gt, class Tds>
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::vertex_descriptor
target(typename boost::graph_traits< Triangulation_2<Gt,Tds> >::halfedge_descriptor e,
const Triangulation_2<Gt,Tds>& g)
{
return e.first->vertex(g.cw(e.second));
}
template <class Gt, class Tds>
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::face_descriptor
face(typename boost::graph_traits< Triangulation_2<Gt,Tds> >::halfedge_descriptor e,
const Triangulation_2<Gt,Tds>&)
{
return e.first;
}
template <class Gt, class Tds>
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::halfedge_descriptor
halfedge(typename boost::graph_traits< Triangulation_2<Gt,Tds> >::face_descriptor f,
const Triangulation_2<Gt,Tds>&)
{
typedef typename boost::graph_traits< Triangulation_2<Gt,Tds> >::halfedge_descriptor halfedge_descriptor;
return halfedge_descriptor(f,0);
}
template <class Gt, class Tds>
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::halfedge_descriptor
halfedge(typename boost::graph_traits< Triangulation_2<Gt,Tds> >::vertex_descriptor v,
const Triangulation_2<Gt,Tds>& g)
{
typedef typename boost::graph_traits< Triangulation_2<Gt,Tds> >::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits< Triangulation_2<Gt,Tds> >::face_descriptor face_descriptor;
face_descriptor fd = v->face();
int i = fd->index(v);
return halfedge_descriptor(fd,g.ccw(i));
}
template <class Gt, class Tds>
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::halfedge_descriptor
halfedge(typename boost::graph_traits< Triangulation_2<Gt,Tds> >::edge_descriptor e,
const Triangulation_2<Gt,Tds>&)
{
typedef typename boost::graph_traits< Triangulation_2<Gt,Tds> >::halfedge_descriptor halfedge_descriptor;
return halfedge_descriptor(e.first,e.second);
}
template <class Gt, class Tds>
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::edge_descriptor
edge(typename boost::graph_traits< Triangulation_2<Gt,Tds> >::halfedge_descriptor e,
const Triangulation_2<Gt,Tds>&)
{
typedef typename boost::graph_traits< Triangulation_2<Gt,Tds> >::edge_descriptor edge_descriptor;
return edge_descriptor(e.first,e.second);
}
template <class Gt, class Tds>
std::pair<typename boost::graph_traits< Triangulation_2<Gt,Tds> >::edge_descriptor,
bool>
edge(typename boost::graph_traits< Triangulation_2<Gt,Tds> >::vertex_descriptor u,
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::vertex_descriptor v,
const Triangulation_2<Gt,Tds>& g)
{
typedef typename boost::graph_traits< Triangulation_2<Gt,Tds> >::edge_descriptor edge_descriptor;
typename Triangulation_2<Gt,Tds>::Edge_circulator c = g.incident_edges(u), done(c);
if (c != 0) {
do {
// find the index of the other vertex of *c
int indv = 3 - c->first->index(u) - c->second;
if(c->first->vertex(indv) == v)
return std::make_pair(edge_descriptor(c->first, c->second), true);
} while (++c != done);
}
return std::make_pair(edge_descriptor(), false);
}
template <class Gt, class Tds>
std::pair<typename boost::graph_traits<Triangulation_2<Gt,Tds> >::halfedge_descriptor,
bool>
halfedge(typename boost::graph_traits<Triangulation_2<Gt,Tds> >::vertex_descriptor u,
typename boost::graph_traits<Triangulation_2<Gt,Tds> >::vertex_descriptor v,
const Triangulation_2<Gt,Tds>& g)
{
typedef typename boost::graph_traits< Triangulation_2<Gt,Tds> >::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits< Triangulation_2<Gt,Tds> >::edge_descriptor edge_descriptor;
typedef typename boost::graph_traits< Triangulation_2<Gt,Tds> >::face_descriptor face_descriptor;
std::pair<edge_descriptor, bool> eb = edge(u, v, g);
if(!eb.second)
return std::make_pair(halfedge_descriptor(), false);
const edge_descriptor& e = eb.first;
if(e.first->vertex(g.ccw(e.first->index(u))) == v)
{
return std::make_pair(halfedge_descriptor(e.first, e.second), true);
}
else
{
face_descriptor nf = e.first->neighbor(e.second);
int idx = nf->index(e.first);
return std::make_pair(halfedge_descriptor(nf, idx), true);
}
}
template <class Gt, class Tds>
inline Iterator_range<typename boost::graph_traits< Triangulation_2<Gt,Tds> >::vertex_iterator>
vertices(const Triangulation_2<Gt,Tds>& g)
{
typedef typename boost::graph_traits< Triangulation_2<Gt,Tds> >::vertex_iterator
Iter;
return make_range( Iter(g.all_vertices_begin()), Iter(g.all_vertices_end()) );
}
template <class Gt, class Tds>
inline Iterator_range<typename boost::graph_traits< Triangulation_2<Gt,Tds> >::edge_iterator>
edges(const Triangulation_2<Gt,Tds>& g)
{
return make_range(g.all_edges_begin(), g.all_edges_end());
}
template <class Gt, class Tds>
inline Iterator_range<typename boost::graph_traits< Triangulation_2<Gt,Tds> >::halfedge_iterator >
halfedges(const Triangulation_2<Gt,Tds>& g)
{
return make_range(g.all_halfedges_begin(), g.all_halfedges_end());
}
template <class Gt, class Tds>
inline Iterator_range<typename boost::graph_traits< Triangulation_2<Gt,Tds> >::face_iterator >
faces(const Triangulation_2<Gt,Tds>& g)
{
typedef typename boost::graph_traits< Triangulation_2<Gt,Tds> >::face_iterator
Iter;
return make_range( Iter(g.all_faces_begin()), Iter(g.all_faces_end()) );
}
template <class Gt, class Tds>
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::degree_size_type
out_degree(
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::vertex_descriptor u,
const Triangulation_2<Gt,Tds>& g)
{
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::degree_size_type deg = 0;
typename Triangulation_2<Gt,Tds>::Edge_circulator c = g.incident_edges(u), done(c);
if ( c != 0) {
do {
++deg;
} while (++c != done);
}
return deg;
}
template <class Gt, class Tds>
inline Iterator_range<typename boost::graph_traits< Triangulation_2<Gt,Tds> >::out_edge_iterator >
out_edges(
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::vertex_descriptor u,
const Triangulation_2<Gt,Tds>& g)
{
typename Triangulation_2<Gt,Tds>::Edge_circulator ec(u,u->face());
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::degree_size_type out_deg = out_degree(u,g);
typedef typename boost::graph_traits< Triangulation_2<Gt,Tds> >
::out_edge_iterator Iter;
return make_range( Iter(ec), Iter(ec,out_deg) );
}
template <class Gt, class Tds>
inline Iterator_range<typename boost::graph_traits< Triangulation_2<Gt,Tds> >::in_edge_iterator >
in_edges(
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::vertex_descriptor u,
const Triangulation_2<Gt,Tds>& g)
{
typename Triangulation_2<Gt,Tds>::Edge_circulator ec(u,u->face());
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::degree_size_type out_deg = out_degree(u,g);
typedef typename boost::graph_traits< Triangulation_2<Gt,Tds> >
::in_edge_iterator Iter;
return make_range( Iter(ec), Iter(ec,out_deg) );
}
template <class Gt, class Tds>
inline Iterator_range<typename boost::graph_traits< Triangulation_2<Gt,Tds> >::adjacency_iterator>
adjacent_vertices(
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::vertex_descriptor u,
const Triangulation_2<Gt,Tds>& g)
{
typename Triangulation_2<Gt,Tds>::Vertex_circulator vc = out_edge_iterator(u,u.face());
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::degree_size_type out_deg = out_degree(u,g);
typedef typename boost::graph_traits< Triangulation_2<Gt,Tds> >
::adjacency_iterator Iter;
return make_range( Iter(vc), Iter(vc,out_deg) );
}
template <class Gt, class Tds>
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::vertices_size_type
num_vertices(const Triangulation_2<Gt,Tds>& g)
{
return g.tds().number_of_vertices();
}
template <class Gt, class Tds>
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::edges_size_type
num_edges(const Triangulation_2<Gt,Tds>& g)
{
return g.tds().number_of_vertices() + g.tds().number_of_faces() - 2;
}
template <class Gt, class Tds>
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::halfedges_size_type
num_halfedges(const Triangulation_2<Gt,Tds>& g)
{
return num_edges(g) * 2;
}
template <class Gt, class Tds>
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::faces_size_type
num_faces(const Triangulation_2<Gt,Tds>& g)
{
return g.tds().number_of_faces();
}
template <class Gt, class Tds>
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::degree_size_type
in_degree(
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::vertex_descriptor u,
const Triangulation_2<Gt,Tds>& g)
{
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::degree_size_type deg = 0;
typename Triangulation_2<Gt,Tds>::Edge_circulator c = g.incident_edges(u), done(c);
if ( c != 0) {
do {
++deg;
} while (++c != done);
}
return deg;
}
template <class Gt, class Tds>
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::degree_size_type
degree(
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::vertex_descriptor u,
const Triangulation_2<Gt,Tds>& g)
{
typename boost::graph_traits< Triangulation_2<Gt,Tds> >::degree_size_type deg = 0;
typename Triangulation_2<Gt,Tds>::Edge_circulator c = g.incident_edges(u), done(c);
if ( c != 0) {
do {
++deg;
} while (++c != done);
}
return deg;
}
// property maps
template <class Gt, class Tds>
class T2_vertex_id_map
: public boost::put_get_helper<int, T2_vertex_id_map<Gt,Tds> >
{
public:
typedef boost::readable_property_map_tag category;
typedef int value_type;
typedef int reference;
typedef typename CGAL::Triangulation_2<Gt,Tds>::Vertex_handle key_type;
T2_vertex_id_map()
{}
long operator[](key_type vh) const {
return vh->id();
}
};
template <class Gt, class Tds>
class T2_vertex_point_map
{
public:
typedef boost::lvalue_property_map_tag category;
typedef typename Tds::Vertex::Point value_type;
typedef value_type& reference;
typedef typename CGAL::Triangulation_2<Gt,Tds>::Vertex_handle key_type;
friend reference get(T2_vertex_point_map<Gt,Tds>, key_type vh)
{
return vh->point();
}
friend void put(T2_vertex_point_map<Gt,Tds>, key_type vh, reference v)
{
vh->point() = v;
}
reference operator[](key_type vh) const {
return vh->point();
}
};
template <class Gt, class Tds>
class T2_edge_id_map
: public boost::put_get_helper<int, T2_edge_id_map<Gt,Tds> >
{
public:
typedef boost::readable_property_map_tag category;
typedef int value_type;
typedef int reference;
typedef typename CGAL::Triangulation_2<Gt,Tds>::Edge key_type;
T2_edge_id_map()
{}
long operator[](key_type e) const {
return (3 * e.first.id()) + e.second;
}
};
template <class Gt, class Tds>
class T2_edge_weight_map
: public boost::put_get_helper<typename Gt::FT, T2_edge_weight_map<Gt, Tds> >
{
private:
const CGAL::Triangulation_2<Gt,Tds>& tr;
public:
typedef boost::readable_property_map_tag category;
typedef typename Gt::FT value_type;
typedef value_type reference;
typedef typename CGAL::Triangulation_2<Gt,Tds>::Edge key_type;
T2_edge_weight_map(const CGAL::Triangulation_2<Gt,Tds>& tr_)
: tr(tr_)
{ }
value_type operator[](key_type e) const {
return approximate_sqrt(tr.segment(e).squared_length());
}
};
template <class Gt, class Tds>
inline T2_vertex_id_map<Gt,Tds>
get(boost::vertex_index_t, const Triangulation_2<Gt,Tds>&) {
T2_vertex_id_map<Gt,Tds> m;
return m;
}
template <class Gt, class Tds>
inline T2_vertex_point_map<Gt,Tds>
get(boost::vertex_point_t, const Triangulation_2<Gt,Tds>&) {
T2_vertex_point_map<Gt,Tds> m;
return m;
}
template <class Gt, class Tds>
inline T2_edge_id_map<Gt,Tds>
get(boost::edge_index_t, const Triangulation_2<Gt,Tds>&) {
T2_edge_id_map<Gt,Tds> m;
return m;
}
template <class Gt, class Tds>
inline T2_edge_weight_map<Gt,Tds>
get(boost::edge_weight_t, const Triangulation_2<Gt,Tds>& g) {
T2_edge_weight_map<Gt,Tds> m(g);
return m;
}
template <class Tag>
struct T2_property_map { };
template <>
struct T2_property_map<boost::vertex_index_t> {
template <class Gt, class Tds>
struct bind_ {
typedef T2_vertex_id_map<Gt,Tds> type;
typedef T2_vertex_id_map<Gt,Tds> const_type;
};
};
template <>
struct T2_property_map<boost::vertex_point_t> {
template <class Gt, class Tds>
struct bind_ {
typedef T2_vertex_point_map<Gt,Tds> type;
typedef T2_vertex_point_map<Gt,Tds> const_type;
};
};
template <>
struct T2_property_map<boost::edge_index_t> {
template <class Gt, class Tds>
struct bind_ {
typedef T2_edge_id_map<Gt,Tds> type;
typedef T2_edge_id_map<Gt,Tds> const_type;
};
};
template <>
struct T2_property_map<boost::edge_weight_t> {
template <class Gt, class Tds>
struct bind_ {
typedef T2_edge_weight_map<Gt,Tds> type;
typedef T2_edge_weight_map<Gt,Tds> const_type;
};
};
} // namespace CGAL
namespace boost {
// g++ 'enumeral_type' in template unification not implemented workaround
template <class Gt, class Tds, class Tag>
struct property_map<CGAL::Triangulation_2<Gt,Tds>, Tag> {
typedef typename
CGAL::T2_property_map<Tag>::template bind_<Gt,Tds> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
// see struct property_map in Polyehdron for an explanation
template <class Gt, class Tds, class Tag>
struct property_map<const CGAL::Triangulation_2<Gt,Tds>, Tag> {
typedef typename
CGAL::T2_property_map<Tag>::template bind_<Gt,Tds> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
} // namespace boost
namespace CGAL {
template <class Gt, class Tds, class PropertyTag, class Key>
inline
typename boost::property_traits<
typename boost::property_map<Triangulation_2<Gt,Tds>,PropertyTag>::const_type>::value_type
get(PropertyTag p, const Triangulation_2<Gt,Tds>& g, const Key& key) {
return get(get(p, g), key);
}
template <class Gt, class Tds, class PropertyTag, class Key,class Value>
inline void
put(PropertyTag p, Triangulation_2<Gt,Tds>& g,
const Key& key, const Value& value)
{
typedef typename boost::property_map<Triangulation_2<Gt,Tds>, PropertyTag>::type Map;
Map pmap = get(p, g);
put(pmap, key, value);
}
} // namespace CGAL
namespace boost {
// What are those needed for ???
template <typename Gt, typename Tds>
struct edge_property_type<CGAL::Triangulation_2<Gt,Tds> > {
typedef void type;
};
template <typename Gt, typename Tds>
struct vertex_property_type<CGAL::Triangulation_2<Gt,Tds> > {
typedef void type;
};
} // namespace boost
namespace std {
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable:4099) // For VC10 it is class hash
#endif
#ifndef CGAL_CFG_NO_STD_HASH
template < class Tr>
struct hash<CGAL::detail::T2_halfedge_descriptor<Tr> > {
std::size_t operator()(const CGAL::detail::T2_halfedge_descriptor<Tr>& e) const
{
return hash_value(e);
}
};
#endif // CGAL_CFG_NO_STD_HASH
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
} // namespace std
#include <CGAL/boost/graph/internal/graph_traits_2D_triangulation.h>
#endif // CGAL_GRAPH_TRAITS_TRIANGULATION_2_H

View File

@ -21,306 +21,17 @@
#ifndef CGAL_GRAPH_TRAITS_TRIANGULATION_HIERARCHY_2_H
#define CGAL_GRAPH_TRAITS_TRIANGULATION_HIERARCHY_2_H
// include this to avoid a VC15 warning
#include <CGAL/boost/graph/named_function_params.h>
#include <boost/config.hpp>
#include <boost/iterator_adaptors.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <CGAL/boost/graph/graph_traits_Triangulation_2.h>
#include <CGAL/Triangulation_hierarchy_2.h>
#include <CGAL/boost/graph/properties_Triangulation_hierarchy_2.h>
// The functions and classes in this file allows the user to
// treat a CGAL Triangulation_hierarchy_2 object as a boost graph "as is". No
// wrapper is needed for the Triangulation_hierarchy_2 object.
// treat a CGAL Delaunay_triangulation_2 object as a boost graph "as is". No
// wrapper is needed for the Constrained_triangulation_2 object.
#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename Tr
#define CGAL_2D_TRIANGULATION CGAL::Triangulation_hierarchy_2<Tr>
#define CGAL_2D_TRIANGULATION_TEMPLATES Tr
namespace boost {
template <class Tr>
struct graph_traits< CGAL::Triangulation_hierarchy_2<Tr> > {
struct DT2_graph_traversal_category :
public virtual bidirectional_graph_tag,
public virtual adjacency_graph_tag,
public virtual edge_list_graph_tag,
public virtual vertex_list_graph_tag { };
typedef typename boost::graph_traits<Tr>::vertex_descriptor vertex_descriptor;
typedef typename boost::graph_traits<Tr>::face_descriptor face_descriptor;
typedef typename boost::graph_traits<Tr>::edge_descriptor edge_descriptor;
typedef typename boost::graph_traits<Tr>::edge_iterator edge_iterator;
typedef typename boost::graph_traits<Tr>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<Tr>::halfedge_iterator halfedge_iterator;
typedef typename boost::graph_traits<Tr>::vertex_iterator vertex_iterator;
typedef typename boost::graph_traits<Tr>::face_iterator face_iterator;
typedef typename boost::graph_traits<Tr>::out_edge_iterator out_edge_iterator;
typedef typename boost::graph_traits<Tr>::in_edge_iterator in_edge_iterator;
typedef typename boost::graph_traits<Tr>::Incident_vertices_iterator Incident_vertices_iterator;
typedef Incident_vertices_iterator adjacency_iterator;
typedef undirected_tag directed_category;
typedef disallow_parallel_edge_tag edge_parallel_category;
typedef DT2_graph_traversal_category traversal_category;
typedef typename boost::graph_traits<Tr>::size_type size_type;
typedef size_type vertices_size_type;
typedef size_type edges_size_type;
typedef size_type halfedges_size_type;
typedef size_type faces_size_type;
typedef size_type degree_size_type;
// nulls
static vertex_descriptor null_vertex() { return vertex_descriptor(); }
static face_descriptor null_face() { return face_descriptor(); }
static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); }
};
} // namespace boost
namespace CGAL {
template <class Tr>
typename boost::graph_traits< CGAL::Triangulation_hierarchy_2<Tr> >::vertex_descriptor
source(typename boost::graph_traits< CGAL::Triangulation_hierarchy_2<Tr> >::edge_descriptor e,
const CGAL::Triangulation_hierarchy_2<Tr>& g)
{
return e.first->vertex(g.ccw(e.second));
}
template <class Tr>
typename boost::graph_traits< CGAL::Triangulation_hierarchy_2<Tr> >::vertex_descriptor
target(typename boost::graph_traits< CGAL::Triangulation_hierarchy_2<Tr> >::edge_descriptor e,
const CGAL::Triangulation_hierarchy_2<Tr>& g)
{
return e.first->vertex(g.cw(e.second));
}
template <class Tr>
inline std::pair<
typename boost::graph_traits< CGAL::Triangulation_hierarchy_2<Tr> >::out_edge_iterator,
typename boost::graph_traits< CGAL::Triangulation_hierarchy_2<Tr> >::out_edge_iterator >
out_edges(
typename boost::graph_traits< CGAL::Triangulation_hierarchy_2<Tr> >::vertex_descriptor u,
const CGAL::Triangulation_hierarchy_2<Tr>& g)
{
typename CGAL::Triangulation_hierarchy_2<Tr>::Edge_circulator ec(u,u->face());
typename boost::graph_traits< CGAL::Triangulation_hierarchy_2<Tr> >::degree_size_type out_deg = out_degree(u,g);
typedef typename boost::graph_traits< CGAL::Triangulation_hierarchy_2<Tr> >
::out_edge_iterator Iter;
return std::make_pair( Iter(ec), Iter(ec,out_deg) );
}
template <class Tr>
inline std::pair<
typename boost::graph_traits< CGAL::Triangulation_hierarchy_2<Tr> >::in_edge_iterator,
typename boost::graph_traits< CGAL::Triangulation_hierarchy_2<Tr> >::in_edge_iterator >
in_edges(
typename boost::graph_traits< CGAL::Triangulation_hierarchy_2<Tr> >::vertex_descriptor u,
const CGAL::Triangulation_hierarchy_2<Tr>& g)
{
typename CGAL::Triangulation_hierarchy_2<Tr>::Edge_circulator ec(u,u->face());
typename boost::graph_traits< CGAL::Triangulation_hierarchy_2<Tr> >::degree_size_type out_deg = out_degree(u,g);
typedef typename boost::graph_traits< CGAL::Triangulation_hierarchy_2<Tr> >
::in_edge_iterator Iter;
return std::make_pair( Iter(ec), Iter(ec,out_deg) );
}
// property maps
template <class Tr>
class TH2_vertex_id_map
: public boost::put_get_helper<int, TH2_vertex_id_map<Tr> >
{
public:
typedef boost::readable_property_map_tag category;
typedef int value_type;
typedef int reference;
typedef typename CGAL::Triangulation_hierarchy_2<Tr>::Vertex_handle key_type;
TH2_vertex_id_map()
{}
long operator[](key_type vh) const {
return vh->id();
}
};
template <class Tr>
class TH2_vertex_point_map
{
public:
typedef boost::lvalue_property_map_tag category;
typedef typename CGAL::Triangulation_hierarchy_2<Tr>::Point value_type;
typedef value_type& reference;
typedef typename CGAL::Triangulation_hierarchy_2<Tr>::Vertex_handle key_type;
friend reference get(TH2_vertex_point_map<Tr>, key_type vh)
{
return vh->point();
}
friend void put(TH2_vertex_point_map<Tr>, key_type vh, reference v)
{
vh->point()=v;
}
reference operator[](key_type vh) const {
return vh->point();
}
};
template <class Tr>
class TH2_edge_id_map
: public boost::put_get_helper<int, TH2_edge_id_map<Tr> >
{
public:
typedef boost::readable_property_map_tag category;
typedef int value_type;
typedef int reference;
typedef typename CGAL::Triangulation_hierarchy_2<Tr>::Edge key_type;
TH2_edge_id_map()
{}
long operator[](key_type e) const {
return (3 * e.first.id()) + e.second;
}
};
template <class Tr>
class TH2_edge_weight_map
: public boost::put_get_helper<typename Tr::Geom_traits::FT, TH2_edge_weight_map<Tr> >
{
private:
const CGAL::Triangulation_hierarchy_2<Tr>& tr;
public:
typedef boost::readable_property_map_tag category;
typedef typename Tr::Geom_traits::FT value_type;
typedef value_type reference;
typedef typename CGAL::Triangulation_hierarchy_2<Tr>::Edge key_type;
TH2_edge_weight_map(const CGAL::Triangulation_hierarchy_2<Tr>& tr_)
: tr(tr_)
{ }
typename Tr::Geom_traits::FT operator[](key_type e) const {
return approximate_sqrt(tr.segment(e).squared_length());
}
};
template <class Tr>
inline TH2_vertex_id_map<Tr>
get(boost::vertex_index_t, const CGAL::Triangulation_hierarchy_2<Tr>& ) {
TH2_vertex_id_map<Tr> m;
return m;
}
template <class Tr>
inline TH2_vertex_point_map<Tr>
get(boost::vertex_point_t, const CGAL::Triangulation_hierarchy_2<Tr>& ) {
TH2_vertex_point_map<Tr> m;
return m;
}
template <class Tr>
inline TH2_edge_id_map<Tr>
get(boost::edge_index_t, const CGAL::Triangulation_hierarchy_2<Tr>& ) {
TH2_edge_id_map<Tr> m;
return m;
}
template <class Tr>
inline TH2_edge_weight_map<Tr>
get(boost::edge_weight_t, const CGAL::Triangulation_hierarchy_2<Tr>& g) {
TH2_edge_weight_map<Tr> m(g);
return m;
}
template <class Tag>
struct TH2_property_map { };
template <>
struct TH2_property_map<boost::vertex_index_t> {
template <class Tr>
struct bind_ {
typedef TH2_vertex_id_map<Tr> type;
typedef TH2_vertex_id_map<Tr> const_type;
};
};
template <>
struct TH2_property_map<boost::vertex_point_t> {
template <class Tr>
struct bind_ {
typedef TH2_vertex_point_map<Tr> type;
typedef TH2_vertex_point_map<Tr> const_type;
};
};
template <>
struct TH2_property_map<boost::edge_index_t> {
template <class Tr>
struct bind_ {
typedef TH2_edge_id_map<Tr> type;
typedef TH2_edge_id_map<Tr> const_type;
};
};
template <>
struct TH2_property_map<boost::edge_weight_t> {
template <class Tr>
struct bind_ {
typedef TH2_edge_weight_map<Tr> type;
typedef TH2_edge_weight_map<Tr> const_type;
};
};
} // namespace CGAL
namespace boost {
// g++ 'enumeral_type' in template unification not implemented workaround
template <class Tr, class Tag>
struct property_map<CGAL::Triangulation_hierarchy_2<Tr>, Tag> {
typedef typename
CGAL::TH2_property_map<Tag>::template bind_<Tr> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
// see struct property_map in Polyhedron for an explanation
template <class Tr, class Tag>
struct property_map<const CGAL::Triangulation_hierarchy_2<Tr>, Tag> {
typedef typename
CGAL::TH2_property_map<Tag>::template bind_<Tr> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
// What are those needed for ???
template <typename Tr>
struct edge_property_type<CGAL::Triangulation_hierarchy_2<Tr> > {
typedef void type;
};
template <typename Tr>
struct vertex_property_type<CGAL::Triangulation_hierarchy_2<Tr> > {
typedef void type;
};
} // namespace boost
#include <CGAL/boost/graph/internal/graph_traits_2D_triangulation.h>
#endif // CGAL_GRAPH_TRAITS_TRIANGULATION_HIERARCHY_2_H

View File

@ -0,0 +1,473 @@
// Copyright (c) 2007, 2019 GeometryFactory (France). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
// Author(s) : Mael Rouxel-Labbé,
// Andreas Fabri,
// Fernando Cacciola
#ifndef CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS
#error CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS is not defined
#endif
#ifndef CGAL_2D_TRIANGULATION
#error CGAL_2D_TRIANGULATION is not defined
#endif
#ifndef CGAL_2D_TRIANGULATION_TEMPLATES
#error CGAL_2D_TRIANGULATION_TEMPLATES is not defined
#endif
#include <CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h>
#include <CGAL/Iterator_range.h>
#include <CGAL/iterator.h>
#include <CGAL/use.h>
#include <boost/config.hpp>
#include <boost/iterator_adaptors.hpp>
#include <boost/graph/graph_traits.hpp>
#include <utility>
namespace boost {
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
struct graph_traits< CGAL_2D_TRIANGULATION >
{
typedef CGAL_2D_TRIANGULATION Triangulation;
struct T2_graph_traversal_category :
public virtual bidirectional_graph_tag,
public virtual adjacency_graph_tag,
public virtual edge_list_graph_tag,
public virtual vertex_list_graph_tag
{ };
typedef typename Triangulation::Vertex_handle vertex_descriptor;
typedef CGAL::internal::T2_halfedge_descriptor<Triangulation> halfedge_descriptor;
typedef CGAL::internal::T2_edge_descriptor<Triangulation> edge_descriptor;
typedef typename Triangulation::Face_handle face_descriptor;
// We need to go from 'Finite_vertex_iterator' to 'Vertex_handle' (and even more
// in the case of RT2, since it has also a hidden filter)
typedef CGAL::internal::Dereference_to_handle_enforcer<
Triangulation,
typename Triangulation::Finite_vertices_iterator,
vertex_descriptor> vertex_iterator;
typedef CGAL::internal::Dereference_to_handle_enforcer<
Triangulation,
typename Triangulation::Finite_faces_iterator,
face_descriptor> face_iterator;
typedef CGAL::internal::T2_halfedge_iterator<Triangulation,
typename Triangulation::Finite_edges_iterator> halfedge_iterator;
typedef CGAL::internal::T2_edge_iterator<Triangulation,
typename Triangulation::Finite_edges_iterator> edge_iterator;
typedef CGAL::internal::T2_vertex_circulator<Triangulation> Vertex_circulator;
typedef CGAL::Counting_iterator<Vertex_circulator> adjacency_iterator;
typedef CGAL::internal::In_edge_circulator<Triangulation> In_edge_circ;
typedef CGAL::Counting_iterator<In_edge_circ> in_edge_iterator;
typedef CGAL::internal::Out_edge_circulator<Triangulation> Out_edge_circ;
typedef CGAL::Counting_iterator<Out_edge_circ> out_edge_iterator;
typedef undirected_tag directed_category;
typedef disallow_parallel_edge_tag edge_parallel_category;
typedef T2_graph_traversal_category traversal_category;
typedef typename Triangulation::size_type size_type;
typedef size_type vertices_size_type;
typedef size_type halfedges_size_type;
typedef size_type edges_size_type;
typedef size_type faces_size_type;
typedef size_type degree_size_type;
// nulls
static vertex_descriptor null_vertex() { return vertex_descriptor(); }
static halfedge_descriptor null_halfedge() { return halfedge_descriptor(); }
static face_descriptor null_face() { return face_descriptor(); }
};
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
struct graph_traits<const CGAL_2D_TRIANGULATION >
: public graph_traits< CGAL_2D_TRIANGULATION >
{ };
} // namespace boost
namespace CGAL {
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor
source(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor e,
const CGAL_2D_TRIANGULATION& g)
{
CGAL_precondition(!g.is_infinite(e));
return e.first->vertex(g.ccw(e.second));
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor
source(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor h,
const CGAL_2D_TRIANGULATION& g)
{
CGAL_precondition(!g.is_infinite(std::make_pair(h.first, h.second)));
return h.first->vertex(g.ccw(h.second));
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor
target(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor e,
const CGAL_2D_TRIANGULATION& g)
{
CGAL_precondition(!g.is_infinite(e));
return e.first->vertex(g.cw(e.second));
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor
target(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor h,
const CGAL_2D_TRIANGULATION& g)
{
CGAL_precondition(!g.is_infinite(std::make_pair(h.first, h.second)));
return h.first->vertex(g.cw(h.second));
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor
next(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor h,
const CGAL_2D_TRIANGULATION& g)
{
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_descriptor face_descriptor;
CGAL_precondition(!g.is_infinite(std::make_pair(h.first, h.second)));
face_descriptor f = h.first;
int i = h.second;
if(!g.is_infinite(f))
return halfedge_descriptor(f, g.ccw(i));
// Now, 'h' is border halfedge, move on to the adjacent infinite face
face_descriptor neigh_f = f->neighbor(g.ccw(i));
return halfedge_descriptor(neigh_f, g.ccw(neigh_f->index(f)));
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor
prev(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor h,
const CGAL_2D_TRIANGULATION& g)
{
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_descriptor face_descriptor;
CGAL_precondition(!g.is_infinite(std::make_pair(h.first, h.second)));
face_descriptor f = h.first;
int i = h.second;
if(!g.is_infinite(f))
return halfedge_descriptor(f, g.cw(i));
// Now, 'h' is border halfedge, move on to the adjacent infinite face
face_descriptor neigh_f = f->neighbor(g.cw(i));
return halfedge_descriptor(neigh_f, g.cw(neigh_f->index(f)));
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor
opposite(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor h,
const CGAL_2D_TRIANGULATION& g)
{
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor;
CGAL_precondition(!g.is_infinite(std::make_pair(h.first, h.second)));
return halfedge_descriptor(g.mirror_edge(typename CGAL_2D_TRIANGULATION::Edge(h.first, h.second)));
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_descriptor
face(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor h,
const CGAL_2D_TRIANGULATION& g)
{
if(g.is_infinite(h.first))
return boost::graph_traits< CGAL_2D_TRIANGULATION >::null_face();
else
return h.first;
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor
halfedge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_descriptor f,
const CGAL_2D_TRIANGULATION& g)
{
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor;
CGAL_USE(g);
CGAL_precondition(!g.is_infinite(f));
return halfedge_descriptor(f, 0);
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor
halfedge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v,
const CGAL_2D_TRIANGULATION& g)
{
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_descriptor face_descriptor;
CGAL_precondition(!g.is_infinite(v));
face_descriptor f = v->face();
int i = f->index(v);
while(g.is_infinite(f))
{
f = f->neighbor(g.cw(i));
i = f->index(v);
}
return halfedge_descriptor(f, g.ccw(i));
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor
halfedge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor e,
const CGAL_2D_TRIANGULATION& g)
{
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor;
CGAL_USE(g);
CGAL_precondition(!g.is_infinite(e));
return halfedge_descriptor(e.first, e.second);
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor
edge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor h,
const CGAL_2D_TRIANGULATION& g)
{
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor edge_descriptor;
CGAL_USE(g);
CGAL_precondition(!g.is_infinite(std::make_pair(h.first, h.second)));
return edge_descriptor(h.first, h.second);
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
std::pair<typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor,
bool>
edge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u,
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v,
const CGAL_2D_TRIANGULATION& g)
{
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor edge_descriptor;
CGAL_precondition(!g.is_infinite(u));
CGAL_precondition(!g.is_infinite(v));
typename CGAL_2D_TRIANGULATION::Edge_circulator c = g.incident_edges(u), done(c);
if(c != 0)
{
do
{
if(!g.is_infinite(*c))
{
// find the index of the other vertex of *c
int indv = 3 - c->first->index(u) - c->second;
if(c->first->vertex(indv) == v)
return std::make_pair(edge_descriptor(c->first, c->second), true);
}
} while (++c != done);
}
return std::make_pair(edge_descriptor(), false);
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
std::pair<typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor,
bool>
halfedge(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor u,
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v,
const CGAL_2D_TRIANGULATION& g)
{
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_descriptor edge_descriptor;
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_descriptor face_descriptor;
CGAL_precondition(!g.is_infinite(u));
CGAL_precondition(!g.is_infinite(v));
std::pair<edge_descriptor, bool> eb = edge(u, v, g);
if(!eb.second)
return std::make_pair(halfedge_descriptor(), false);
const edge_descriptor& e = eb.first;
if(e.first->vertex(g.ccw(e.first->index(u))) == v)
{
return std::make_pair(halfedge_descriptor(e.first, e.second), true);
}
else
{
face_descriptor nf = e.first->neighbor(e.second);
int idx = nf->index(e.first);
return std::make_pair(halfedge_descriptor(nf, idx), true);
}
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
inline Iterator_range<typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_iterator>
vertices(const CGAL_2D_TRIANGULATION& g)
{
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_iterator Iter;
return make_range( Iter(g.finite_vertices_begin()), Iter(g.finite_vertices_end()) );
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
inline Iterator_range<typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_iterator >
halfedges(const CGAL_2D_TRIANGULATION& g)
{
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedge_iterator Iter;
return make_range(Iter(g.finite_edges_begin()), Iter(g.finite_edges_end()));
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
inline Iterator_range<typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_iterator>
edges(const CGAL_2D_TRIANGULATION& g)
{
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edge_iterator Iter;
return make_range(Iter(g.finite_edges_begin()), Iter(g.finite_edges_end()));
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
inline Iterator_range<typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_iterator >
faces(const CGAL_2D_TRIANGULATION& g)
{
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::face_iterator Iter;
return make_range(Iter(g.finite_faces_begin()), Iter(g.finite_faces_end()));
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type
degree(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v,
const CGAL_2D_TRIANGULATION& g)
{
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type deg = 0;
typename CGAL_2D_TRIANGULATION::Edge_circulator c = g.incident_edges(v), done(c);
if(c != 0)
{
do {
if(!g.is_infinite(*c))
++deg;
} while (++c != done);
}
return deg;
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type
in_degree(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v,
const CGAL_2D_TRIANGULATION& g)
{
return degree(v, g);
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type
out_degree(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v,
const CGAL_2D_TRIANGULATION& g)
{
return degree(v, g);
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
inline Iterator_range<typename boost::graph_traits< CGAL_2D_TRIANGULATION >::in_edge_iterator >
in_edges(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v,
const CGAL_2D_TRIANGULATION& g)
{
typedef CGAL::internal::In_edge_circulator< CGAL_2D_TRIANGULATION > Circ;
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::in_edge_iterator Iter;
typename CGAL_2D_TRIANGULATION::Edge_circulator ec(v, v->face());
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type deg = degree(v, g);
return make_range(Iter(Circ(ec, g)), Iter(Circ(ec, g), deg));
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
inline Iterator_range<typename boost::graph_traits< CGAL_2D_TRIANGULATION >::out_edge_iterator >
out_edges(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v,
const CGAL_2D_TRIANGULATION& g)
{
typedef CGAL::internal::Out_edge_circulator< CGAL_2D_TRIANGULATION > Circ;
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::out_edge_iterator Iter;
typename CGAL_2D_TRIANGULATION::Edge_circulator ec(v, v->face());
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type deg = degree(v, g);
return make_range(Iter(Circ(ec, g)), Iter(Circ(ec, g), deg));
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
inline Iterator_range<typename boost::graph_traits< CGAL_2D_TRIANGULATION >::adjacency_iterator>
adjacent_vertices(typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertex_descriptor v,
const CGAL_2D_TRIANGULATION& g)
{
typedef CGAL::internal::T2_vertex_circulator< CGAL_2D_TRIANGULATION > Circ;
typedef typename boost::graph_traits< CGAL_2D_TRIANGULATION >::adjacency_iterator Iter;
typename CGAL_2D_TRIANGULATION::Edge_circulator ec(v, v->face());
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::degree_size_type deg = degree(v, g);
return make_range(Iter(Circ(ec, g)), Iter(Circ(ec, g), deg));
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::vertices_size_type
num_vertices(const CGAL_2D_TRIANGULATION& g)
{
return g.number_of_vertices();
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::faces_size_type
num_faces(const CGAL_2D_TRIANGULATION& g)
{
return g.number_of_faces();
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::edges_size_type
num_edges(const CGAL_2D_TRIANGULATION& g)
{
// Euler characteristic for a triangulated topological disk is V-E+F=1
return num_vertices(g) + num_faces(g) - 1;
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
typename boost::graph_traits< CGAL_2D_TRIANGULATION >::halfedges_size_type
num_halfedges(const CGAL_2D_TRIANGULATION& g)
{
return num_edges(g) * 2;
}
} // namespace CGAL
#undef CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS
#undef CGAL_2D_TRIANGULATION
#undef CGAL_2D_TRIANGULATION_TEMPLATES

View File

@ -0,0 +1,470 @@
// Copyright (c) 2019 GeometryFactory (France). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
// Author(s) : Mael Rouxel-Labbé
#include <CGAL/Iterator_range.h>
#include <CGAL/iterator.h>
#include <CGAL/use.h>
#include <boost/config.hpp>
#include <boost/iterator_adaptors.hpp>
#include <boost/graph/graph_traits.hpp>
#include <utility>
#ifndef CGAL_GRAPH_TRAITS_2D_TRIANGULATION_HELPERS
#define CGAL_GRAPH_TRAITS_2D_TRIANGULATION_HELPERS
namespace CGAL {
namespace internal {
// A triangulation edge is a face handle + an int, and is thus actually a halfedge...
template <class Tr>
struct T2_halfedge_descriptor
: public Tr::Edge
{
typedef typename Tr::Edge Base;
typedef typename Tr::Face_handle Face_handle;
T2_halfedge_descriptor() {}
T2_halfedge_descriptor(Face_handle fh, int i) : Base(fh, i) { }
explicit T2_halfedge_descriptor(const Base& e) : Base(e) { }
T2_halfedge_descriptor(const T2_halfedge_descriptor& h) : Base(h) { }
const Base& base() const { return static_cast<const Base&>(*this); }
T2_halfedge_descriptor& operator=(const T2_halfedge_descriptor& h)
{
this->first = h.first;
this->second = h.second;
return *this;
}
friend std::size_t hash_value(const T2_halfedge_descriptor& e) {
return hash_value(e.first);
}
};
// An edge is just a halfedge, but we give it a complete structure to distinguish it from Tr::Edge
template <typename Tr>
struct T2_edge_descriptor
{
typedef typename Tr::Face_handle Face_handle;
T2_edge_descriptor() : first(), second(0) { }
explicit T2_edge_descriptor(const typename Tr::Edge& e) : first(e.first), second(e.second) { }
T2_edge_descriptor(Face_handle fd, int i) : first(fd), second(i) { }
// so that we can still do stuff like tr.is_finite(edge_descriptor) without any hassle
operator std::pair<Face_handle, int>() const { return std::make_pair(first, second); }
friend std::size_t hash_value(const T2_edge_descriptor& h)
{
if(h.first == Face_handle())
return 0;
return hash_value(h.first < h.first->neighbor(h.second) ? h.first
: h.first->neighbor(h.second));
}
bool operator==(const T2_edge_descriptor& other) const
{
if((first == other.first) && (second == other.second))
return true;
Face_handle fh = first->neighbor(second);
if(other.first != fh)
return false;
int i = fh->index(first);
return (other.second == i);
}
bool operator!=(T2_edge_descriptor& other) const { return ! (*this == other); }
void get_canonical_edge_representation(Face_handle& fh, int& i) const
{
Face_handle neigh_fh = fh->neighbor(i);
Face_handle canonical_fh = (fh < neigh_fh) ? fh : neigh_fh;
int canonical_i = (fh < neigh_fh) ? i : neigh_fh->index(fh);
fh = canonical_fh;
i = canonical_i;
}
bool operator<(const T2_edge_descriptor& other) const
{
if(*this == other)
return false;
Face_handle tfh = first;
int ti = second;
get_canonical_edge_representation(tfh, ti);
Face_handle ofh = other.first;
int oi = other.second;
get_canonical_edge_representation(ofh, oi);
if(tfh < ofh) return true;
if(tfh > ofh) return false;
return ti < oi;
}
Face_handle first;
int second;
};
// A halfedge iterator is just an edge iterator that duplicates everything twice,
// to see the edge from either side.
// Could probably be factorized with T2_edge_iterator, but it's clearer this way.
template <typename Tr, typename EdgeIterator>
struct T2_halfedge_iterator
{
private:
typedef T2_halfedge_iterator<Tr, EdgeIterator> Self;
typedef EdgeIterator Edge_iterator;
typedef T2_halfedge_descriptor<Tr> Descriptor;
typedef typename Tr::Face_handle Face_handle;
public:
typedef Descriptor value_type;
typedef value_type* pointer;
typedef value_type& reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
T2_halfedge_iterator() { }
T2_halfedge_iterator(const Edge_iterator& feit) : it(feit), on_adjacent_face(false) { }
Self& operator++()
{
// If we are on the first face, move to the opposite face. If we are already on the opposite face,
// then it's time to move on the next edge
if(on_adjacent_face) {
++it;
on_adjacent_face = false;
} else {
on_adjacent_face = true;
}
return *this;
}
Self& operator--()
{
// Note that while decreasing, we start from the opposite face
if(on_adjacent_face) {
on_adjacent_face = false;
} else {
--it;
on_adjacent_face = true;
}
return *this;
}
Self operator++(int) { Self tmp = *this; operator++(); return tmp; }
Self operator--(int) { Self tmp = *this; operator--(); return tmp; }
bool operator==(const Self& other) const { return it == other.it; }
bool operator!=(const Self& other) const { return !(*this == other); }
reference operator*() const
{
if(on_adjacent_face)
{
Face_handle neigh_f = it->first->neighbor(it->second);
hd = Descriptor(neigh_f, neigh_f->index(it->first));
return hd;
} else {
hd = Descriptor(it->first, it->second);
return hd;
}
}
private:
Edge_iterator it;
bool on_adjacent_face;
mutable Descriptor hd;
};
template <typename Tr, typename EdgeIterator>
struct T2_edge_iterator
{
private:
typedef T2_edge_iterator<Tr, EdgeIterator> Self;
typedef EdgeIterator Edge_iterator;
typedef T2_edge_descriptor<Tr> Descriptor;
public:
typedef Descriptor value_type;
typedef value_type* pointer;
typedef value_type& reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
T2_edge_iterator() { }
T2_edge_iterator(const Edge_iterator& feit) : it(feit) { }
bool operator==(const Self& other) const { return it == other.it; }
bool operator!=(const Self& other) const { return !(*this == other); }
Self& operator++() { ++it; return *this; }
Self& operator--() { --it; return *this; }
Self operator++(int) { Self tmp = *this; operator++(); return tmp; }
Self operator--(int) { Self tmp = *this; operator--(); return tmp; }
reference operator*() const
{
ed = Descriptor(*it);
return ed;
}
private:
Edge_iterator it;
mutable Descriptor ed;
};
// Must distinguish TDS and triangulations circulators (later are filtered)
template <class Circ, class E>
class TDS2_Out_edge_circulator
: public Circ
{
private:
mutable E e;
public:
typedef E value_type;
typedef E* pointer;
typedef E& reference;
TDS2_Out_edge_circulator() : Circ() {}
TDS2_Out_edge_circulator(Circ c) : Circ(c) {}
const E& operator*() const
{
E ed = static_cast<const Circ*>(this)->operator*();
e = E(ed.first->neighbor(ed.second), ed.first->neighbor(ed.second)->index(ed.first));
return e;
}
};
template <class Circ, class E>
class TDS2_In_edge_circulator
: public Circ
{
private:
mutable E e;
public:
typedef E value_type;
typedef E* pointer;
typedef E& reference;
TDS2_In_edge_circulator() : Circ() {}
TDS2_In_edge_circulator(Circ c) : Circ(c) {}
const E& operator*() const
{
typename Circ::value_type ed = static_cast<const Circ*>(this)->operator*();
e = E(ed);
return e;
}
};
template <typename Tr>
struct T2_edge_circulator
: public Tr::Edge_circulator
{
private:
typedef T2_edge_circulator<Tr> Self;
typedef typename Tr::Edge Edge;
typedef typename Tr::Edge_circulator Base;
public:
typedef T2_edge_descriptor<Tr> value_type;
typedef value_type* pointer;
typedef value_type& reference;
T2_edge_circulator() : Base() { }
T2_edge_circulator(const Base& c, const Tr& tr) : Base(c), tr(&tr), e() { }
// Note that the inf check is on the edge in the circulator, not on 'e', which isn't built yet
Self& operator++() {
do { this->Base::operator++(); } while(tr->is_infinite(this->Base::operator*()));
return *this;
}
Self& operator--() {
do { this->Base::operator--(); } while(tr->is_infinite(this->Base::operator*()));
return *this;
}
Self operator++(int) { Self tmp(*this); ++(*this); return tmp; }
Self operator--(int) { Self tmp(*this); --(*this); return tmp; }
protected:
const Tr* tr;
mutable value_type e;
};
template <typename Tr>
struct In_edge_circulator
: public T2_edge_circulator<Tr>
{
private:
typedef T2_edge_circulator<Tr> Base;
typedef typename Tr::Edge Edge;
typedef typename Tr::Edge_circulator Edge_circulator;
public:
typedef T2_edge_descriptor<Tr> value_type;
typedef value_type* pointer;
typedef value_type& reference;
In_edge_circulator() : Base() { }
In_edge_circulator(const Edge_circulator& c, const Tr& tr) : Base(c, tr) { }
const value_type& operator*() const
{
this->e = value_type(this->Base::operator*());
return this->e;
}
};
template <typename Tr>
struct Out_edge_circulator
: public T2_edge_circulator<Tr>
{
private:
typedef T2_edge_circulator<Tr> Base;
typedef typename Tr::Edge Edge;
typedef typename Tr::Edge_circulator Edge_circulator;
public:
typedef T2_edge_descriptor<Tr> value_type;
typedef value_type* pointer;
typedef value_type& reference;
Out_edge_circulator() : Base() { }
Out_edge_circulator(const Edge_circulator& c, const Tr& tr) : Base(c, tr) { }
const value_type& operator*() const
{
Edge ed(this->Base::operator*());
this->e = value_type(ed.first->neighbor(ed.second),
ed.first->neighbor(ed.second)->index(ed.first));
return this->e;
}
};
template <typename Tr>
struct T2_vertex_circulator
: public In_edge_circulator<Tr>
{
private:
typedef In_edge_circulator<Tr> Base;
typedef T2_edge_descriptor<Tr> edge_descriptor;
typedef typename Tr::Edge_circulator Edge_circulator;
typedef typename Tr::Vertex_handle Vertex_handle;
public:
typedef Vertex_handle value_type;
typedef value_type& reference;
T2_vertex_circulator() : Base() { }
T2_vertex_circulator(const Edge_circulator& c, const Tr& tr) : Base(c, tr) { }
const value_type& operator*() const
{
const edge_descriptor& edge = this->Base::operator*();
v = edge.first->vertex(this->tr->ccw(edge.second));
return v;
}
private:
// Because we wrap the iterator with a Counting_iterator, which returns a ref in its operator*()
mutable Vertex_handle v;
};
template <typename Tr, typename Iterator, typename Handle>
struct Dereference_to_handle_enforcer
: public boost::iterator_adaptor<
Dereference_to_handle_enforcer<Tr, Iterator, Handle>,
Iterator /*base*/,
Handle /*value*/,
boost::use_default,
Handle /*reference*/
>
{
public:
typedef Handle value_type;
private:
typedef Dereference_to_handle_enforcer<Tr, Iterator, Handle> Self;
typedef Iterator I;
typedef boost::iterator_adaptor<Self, I, value_type, boost::use_default, value_type> Base;
public:
Dereference_to_handle_enforcer() { }
explicit Dereference_to_handle_enforcer(const I& i) : Base(i) { }
private:
friend class boost::iterator_core_access;
value_type dereference() const { return value_type(this->base()); }
};
} // namespace internal
} // namespace CGAL
namespace std {
// workaround a bug detected on at least g++ 4.4 where boost::next(Iterator)
// is picked as a candidate for next(h,g)
template <typename Tr>
struct iterator_traits< CGAL::internal::T2_halfedge_descriptor<Tr> >
{
typedef void* iterator_category;
typedef void* difference_type;
typedef void* value_type;
typedef void* reference;
};
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable:4099) // For VC10 it is class hash
#endif
#ifndef CGAL_CFG_NO_STD_HASH
template < class Tr>
struct hash<CGAL::internal::T2_halfedge_descriptor<Tr> >
{
std::size_t operator()(const CGAL::internal::T2_halfedge_descriptor<Tr>& e) const {
return hash_value(e);
}
};
#endif // CGAL_CFG_NO_STD_HASH
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
} // namespace std
#endif // CGAL_GRAPH_TRAITS_2D_TRIANGULATION_HELPERS

View File

@ -0,0 +1,383 @@
// Copyright (c) 2019 GeometryFactory (France). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
// Author(s) : Mael Rouxel-Labbé
#include <CGAL/assertions.h>
#include <CGAL/boost/graph/internal/Has_member_id.h>
#include <CGAL/boost/graph/properties.h>
#ifndef CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS
#error CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS is not defined
#endif
#ifndef CGAL_2D_TRIANGULATION
#error CGAL_2D_TRIANGULATION is not defined
#endif
// note only the properties below are protected by the macro,
// the rest of the file is the shared implementation of properties for all 2D triangulations
#ifndef CGAL_BOOST_GRAPH_PROPERTIES_2D_TRIANGULATION_H
#define CGAL_BOOST_GRAPH_PROPERTIES_2D_TRIANGULATION_H
namespace CGAL {
namespace internal {
template <class Tr>
struct T2_halfedge_descriptor;
template <class Tr>
struct T2_edge_descriptor;
template <typename Tr>
class T2_vertex_point_map
{
public:
typedef boost::lvalue_property_map_tag category;
typedef typename Tr::Point value_type;
typedef value_type& reference;
typedef typename Tr::Vertex_handle key_type;
T2_vertex_point_map() { }
friend reference get(T2_vertex_point_map<Tr>, key_type vh)
{
return vh->point();
}
friend void put(T2_vertex_point_map<Tr>, key_type vh, const value_type& v)
{
vh->point() = v;
}
reference operator[](key_type vh) const { return vh->point(); }
};
template <typename Tr>
class T2_edge_weight_map
: public boost::put_get_helper<typename Tr::Geom_traits::FT,
T2_edge_weight_map<Tr> >
{
public:
typedef boost::readable_property_map_tag category;
typedef typename Tr::Geom_traits::FT value_type;
typedef value_type reference;
typedef CGAL::internal::T2_edge_descriptor<Tr> key_type;
T2_edge_weight_map(const Tr& tr_) : tr(tr_) { }
value_type operator[](key_type e) const { return approximate_sqrt(tr.segment(e).squared_length()); }
private:
const Tr& tr;
};
template <typename Tr>
class T2_vertex_id_map
: public boost::put_get_helper<int, T2_vertex_id_map<Tr> >
{
public:
typedef boost::readable_property_map_tag category;
typedef int value_type;
typedef int reference;
typedef typename Tr::Vertex_handle key_type;
T2_vertex_id_map(const Tr& tr) : tr(tr) { }
value_type operator[](key_type v) const {
CGAL_precondition(!tr.is_infinite(v));
return v->id();
}
const Tr& tr;
};
template <typename Tr>
class T2_halfedge_id_map
: public boost::put_get_helper<int, T2_halfedge_id_map<Tr> >
{
public:
typedef boost::readable_property_map_tag category;
typedef int value_type;
typedef int reference;
typedef CGAL::internal::T2_halfedge_descriptor<Tr> key_type;
typedef typename Tr::Face_handle Face_handle;
T2_halfedge_id_map(const Tr& tr) : tr(tr) { }
// Halfedge id is twice the edge id, and +0/+1 depending whether
// h.first is such that h.first < opposite(h).first --> different ids
value_type operator[](key_type h) const
{
const Face_handle f1 = h.first;
const Face_handle f2 = f1->neighbor(h.second);
CGAL_assertion(!tr.is_infinite(f1) || !tr.is_infinite(f2));
if(tr.is_infinite(f1))
return 2*(3 * f2->id() + f2->index(f1));
else if(tr.is_infinite(f2))
return 2*(3 * f1->id() + h.second) + 1;
else if(f1->id() < f2->id())
return 2*(3 * f1->id() + h.second);
else
return 2*(3 * f2->id() + f2->index(f1)) + 1;
}
private:
const Tr& tr;
};
template <typename Tr>
class T2_edge_id_map
: public boost::put_get_helper<int, T2_edge_id_map<Tr> >
{
public:
typedef boost::readable_property_map_tag category;
typedef int value_type;
typedef int reference;
typedef CGAL::internal::T2_edge_descriptor<Tr> key_type;
typedef typename Tr::Face_handle Face_handle;
T2_edge_id_map(const Tr& tr) : tr(tr) { }
value_type operator[](key_type e) const
{
const Face_handle f1 = e.first;
const Face_handle f2 = f1->neighbor(e.second);
CGAL_assertion(!tr.is_infinite(f1) || !tr.is_infinite(f2));
if(tr.is_infinite(f1))
return 3 * f2->id() + f2->index(f1);
else if(tr.is_infinite(f2))
return 3 * f1->id() + e.second;
else if(f1->id() < f2->id())
return 3 * f1->id() + e.second;
else
return 3 * f2->id() + f2->index(f1);
}
private:
const Tr& tr;
};
template <typename Tr>
class T2_face_id_map
: public boost::put_get_helper<int, T2_face_id_map<Tr> >
{
public:
typedef boost::readable_property_map_tag category;
typedef int value_type;
typedef int reference;
typedef typename Tr::Face_handle key_type;
T2_face_id_map(const Tr& tr) : tr(tr) { }
value_type operator[](key_type f) const {
CGAL_precondition(!tr.is_infinite(f));
return f->id();
}
private:
const Tr& tr;
};
template <typename Tr, typename Tag>
struct T2_property_map { };
template <typename Tr>
struct T2_property_map<Tr, boost::vertex_point_t>
{
typedef internal::T2_vertex_point_map<Tr> type;
typedef internal::T2_vertex_point_map<Tr> const_type;
};
template <typename Tr>
struct T2_property_map<Tr, boost::edge_weight_t>
{
typedef internal::T2_edge_weight_map<Tr> type;
typedef internal::T2_edge_weight_map<Tr> const_type;
};
template <typename Tr>
struct T2_property_map<Tr, boost::vertex_index_t>
{
typedef internal::T2_vertex_id_map<Tr> type;
typedef internal::T2_vertex_id_map<Tr> const_type;
};
template <typename Tr>
struct T2_property_map<Tr, boost::halfedge_index_t>
{
typedef internal::T2_halfedge_id_map<Tr> type;
typedef internal::T2_halfedge_id_map<Tr> const_type;
};
template <typename Tr>
struct T2_property_map<Tr, boost::edge_index_t>
{
typedef internal::T2_edge_id_map<Tr> type;
typedef internal::T2_edge_id_map<Tr> const_type;
};
template <typename Tr>
struct T2_property_map<Tr, boost::face_index_t>
{
typedef internal::T2_face_id_map<Tr> type;
typedef internal::T2_face_id_map<Tr> const_type;
};
} // end namespace internal
} // CGAL
#endif // CGAL_BOOST_GRAPH_PROPERTIES_2D_TRIANGULATION_H
// overloads and specializations in the boost namespace
namespace boost {
// g++ 'enumeral_type' in template unification not implemented workaround
template <CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS, class Tag>
struct property_map<CGAL_2D_TRIANGULATION, Tag>
{
typedef typename CGAL::internal::T2_property_map<CGAL_2D_TRIANGULATION, Tag> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
// see struct property_map in Polyehdron for an explanation
template <CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS, class Tag>
struct property_map<const CGAL_2D_TRIANGULATION, Tag>
{
typedef typename CGAL::internal::T2_property_map<CGAL_2D_TRIANGULATION, Tag> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
} // end namespace boost
namespace CGAL {
template <CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
struct graph_has_property<CGAL_2D_TRIANGULATION, boost::vertex_point_t>
: CGAL::Tag_true{};
template<CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
struct graph_has_property<CGAL_2D_TRIANGULATION, boost::edge_weight_t>
: CGAL::Tag_true{};
template<CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
struct graph_has_property<CGAL_2D_TRIANGULATION, boost::vertex_index_t>
: CGAL::Boolean_tag<
CGAL::internal::Has_member_id<
typename CGAL_2D_TRIANGULATION::Vertex
>::value
>
{};
template<CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
struct graph_has_property<CGAL_2D_TRIANGULATION, boost::halfedge_index_t>
: CGAL::Boolean_tag<
CGAL::internal::Has_member_id<
typename CGAL_2D_TRIANGULATION::Face
>::value
>
{};
template<CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
struct graph_has_property<CGAL_2D_TRIANGULATION, boost::edge_index_t>
: CGAL::Boolean_tag<
CGAL::internal::Has_member_id<
typename CGAL_2D_TRIANGULATION::Face
>::value
>
{};
template<CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
struct graph_has_property<CGAL_2D_TRIANGULATION, boost::face_index_t>
: CGAL::Boolean_tag<
CGAL::internal::Has_member_id<
typename CGAL_2D_TRIANGULATION::Face
>::value
>
{};
// property maps
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
inline internal::T2_vertex_point_map< CGAL_2D_TRIANGULATION >
get(boost::vertex_point_t, const CGAL_2D_TRIANGULATION&)
{
internal::T2_vertex_point_map< CGAL_2D_TRIANGULATION > m;
return m;
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
inline internal::T2_edge_weight_map< CGAL_2D_TRIANGULATION >
get(boost::edge_weight_t, const CGAL_2D_TRIANGULATION& g)
{
internal::T2_edge_weight_map< CGAL_2D_TRIANGULATION > m(g);
return m;
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
inline internal::T2_vertex_id_map< CGAL_2D_TRIANGULATION >
get(boost::vertex_index_t, const CGAL_2D_TRIANGULATION& g)
{
internal::T2_vertex_id_map< CGAL_2D_TRIANGULATION > m(g);
return m;
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
inline internal::T2_halfedge_id_map< CGAL_2D_TRIANGULATION >
get(boost::halfedge_index_t, const CGAL_2D_TRIANGULATION& g)
{
internal::T2_halfedge_id_map< CGAL_2D_TRIANGULATION > m(g);
return m;
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
inline internal::T2_edge_id_map< CGAL_2D_TRIANGULATION >
get(boost::edge_index_t, const CGAL_2D_TRIANGULATION& g)
{
internal::T2_edge_id_map< CGAL_2D_TRIANGULATION > m(g);
return m;
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS >
inline internal::T2_face_id_map< CGAL_2D_TRIANGULATION >
get(boost::face_index_t, const CGAL_2D_TRIANGULATION& g)
{
internal::T2_face_id_map< CGAL_2D_TRIANGULATION > m(g);
return m;
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS, class PropertyTag, class Key>
inline
typename boost::property_traits<
typename boost::property_map< CGAL_2D_TRIANGULATION, PropertyTag>::const_type>::value_type
get(PropertyTag p, const CGAL_2D_TRIANGULATION& g, const Key& key)
{
return get(get(p, g), key);
}
template < CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS, class PropertyTag, class Key, class Value>
inline void
put(PropertyTag p, CGAL_2D_TRIANGULATION& g, const Key& key, const Value& value)
{
typedef typename boost::property_map<CGAL_2D_TRIANGULATION, PropertyTag>::type Map;
Map pmap = get(p, g);
put(pmap, key, value);
}
} // namespace CGAL
#undef CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS
#undef CGAL_2D_TRIANGULATION

View File

@ -0,0 +1,30 @@
// Copyright (c) 2019 GeometryFactory (France). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
// Author(s) : Mael Rouxel-Labbé
#ifndef CGAL_PROPERTIES_CONSTRAINED_DELAUNAY_TRIANGULATION_2_H
#define CGAL_PROPERTIES_CONSTRAINED_DELAUNAY_TRIANGULATION_2_H
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS, typename Itag
#define CGAL_2D_TRIANGULATION CGAL::Constrained_Delaunay_triangulation_2<GT, TDS, Itag>
#include <CGAL/boost/graph/internal/properties_2D_triangulation.h>
#endif /* CGAL_PROPERTIES_CONSTRAINED_DELAUNAY_TRIANGULATION_2_H */

View File

@ -0,0 +1,30 @@
// Copyright (c) 2019 GeometryFactory (France). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
// Author(s) : Mael Rouxel-Labbé
#ifndef CGAL_PROPERTIES_CONSTRAINED_TRIANGULATION_2_H
#define CGAL_PROPERTIES_CONSTRAINED_TRIANGULATION_2_H
#include <CGAL/Constrained_triangulation_2.h>
#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS, typename Itag
#define CGAL_2D_TRIANGULATION CGAL::Constrained_triangulation_2<GT, TDS, Itag>
#include <CGAL/boost/graph/internal/properties_2D_triangulation.h>
#endif /* CGAL_PROPERTIES_CONSTRAINED_TRIANGULATION_2_H */

View File

@ -0,0 +1,30 @@
// Copyright (c) 2019 GeometryFactory (France). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
// Author(s) : Mael Rouxel-Labbé
#ifndef CGAL_PROPERTIES_CONSTRAINED_TRIANGULATION_PLUS_2_H
#define CGAL_PROPERTIES_CONSTRAINED_TRIANGULATION_PLUS_2_H
#include <CGAL/Constrained_triangulation_plus_2.h>
#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename Tr
#define CGAL_2D_TRIANGULATION CGAL::Constrained_triangulation_plus_2<Tr>
#include <CGAL/boost/graph/internal/properties_2D_triangulation.h>
#endif /* CGAL_PROPERTIES_CONSTRAINED_TRIANGULATION_PLUS_2_H */

View File

@ -0,0 +1,30 @@
// Copyright (c) 2019 GeometryFactory (France). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
// Author(s) : Mael Rouxel-Labbé
#ifndef CGAL_PROPERTIES_DELAUNAY_TRIANGULATION_2_H
#define CGAL_PROPERTIES_DELAUNAY_TRIANGULATION_2_H
#include <CGAL/Delaunay_triangulation_2.h>
#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS
#define CGAL_2D_TRIANGULATION CGAL::Delaunay_triangulation_2<GT, TDS>
#include <CGAL/boost/graph/internal/properties_2D_triangulation.h>
#endif /* CGAL_PROPERTIES_DELAUNAY_TRIANGULATION_2_H */

View File

@ -0,0 +1,30 @@
// Copyright (c) 2019 GeometryFactory (France). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
// Author(s) : Mael Rouxel-Labbé
#ifndef CGAL_PROPERTIES_REGULAR_TRIANGULATION_2_H
#define CGAL_PROPERTIES_REGULAR_TRIANGULATION_2_H
#include <CGAL/Regular_triangulation_2.h>
#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS
#define CGAL_2D_TRIANGULATION CGAL::Regular_triangulation_2<GT, TDS>
#include <CGAL/boost/graph/internal/properties_2D_triangulation.h>
#endif /* CGAL_PROPERTIES_REGULAR_TRIANGULATION_2_H */

View File

@ -0,0 +1,30 @@
// Copyright (c) 2019 GeometryFactory (France). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
// Author(s) : Mael Rouxel-Labbé
#ifndef CGAL_PROPERTIES_TRIANGULATION_2_H
#define CGAL_PROPERTIES_TRIANGULATION_2_H
#include <CGAL/Triangulation_2.h>
#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename GT, typename TDS
#define CGAL_2D_TRIANGULATION CGAL::Triangulation_2<GT, TDS>
#include <CGAL/boost/graph/internal/properties_2D_triangulation.h>
#endif /* CGAL_PROPERTIES_TRIANGULATION_2_H */

View File

@ -0,0 +1,354 @@
// Copyright (c) 2019 GeometryFactory (France). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
// Author(s) : Mael Rouxel-Labbé
#ifndef CGAL_PROPERTIES_TRIANGULATION_DATA_STRUCTURE_2_H
#define CGAL_PROPERTIES_TRIANGULATION_DATA_STRUCTURE_2_H
#include <CGAL/Triangulation_data_structure_2.h>
#include <CGAL/boost/graph/internal/graph_traits_2D_triangulation_helper.h>
#include <CGAL/boost/graph/internal/Has_member_id.h>
#include <CGAL/boost/graph/named_function_params.h>
#include <boost/graph/properties.hpp>
namespace CGAL {
namespace internal {
// property maps
template <class VB, class FB>
class TDS2_vertex_point_map
{
public:
typedef boost::lvalue_property_map_tag category;
typedef typename VB::Point value_type;
typedef value_type& reference;
typedef typename CGAL::Triangulation_data_structure_2<VB,FB>::Vertex_handle key_type;
friend reference get(TDS2_vertex_point_map<VB,FB>, key_type vh) { return vh->point(); }
friend void put(TDS2_vertex_point_map<VB,FB>, key_type vh, reference v) { vh->point() = v; }
reference operator[](key_type vh) const { return vh->point(); }
};
template <class VB, class FB>
class TDS2_edge_weight_map
: public boost::put_get_helper<typename VB::FT, TDS2_edge_weight_map<VB, FB> >
{
public:
typedef boost::readable_property_map_tag category;
typedef typename VB::FT value_type;
typedef value_type reference;
typedef typename CGAL::Triangulation_data_structure_2<VB,FB>::Edge key_type;
TDS2_edge_weight_map(const CGAL::Triangulation_data_structure_2<VB,FB>& tds_) : tds(tds_) { }
value_type operator[](key_type e) const { return approximate_sqrt(tds.segment(e).squared_length()); }
private:
const CGAL::Triangulation_data_structure_2<VB,FB>& tds;
};
template <class VB, class FB>
class TDS2_vertex_id_map
: public boost::put_get_helper<int, TDS2_vertex_id_map<VB, FB> >
{
public:
typedef boost::readable_property_map_tag category;
typedef int value_type;
typedef int reference;
typedef typename CGAL::Triangulation_data_structure_2<VB,FB>::Vertex_handle key_type;
TDS2_vertex_id_map() {}
long operator[](key_type vh) const { return vh->id(); }
};
template <class VB, class FB>
class TDS2_halfedge_id_map
: public boost::put_get_helper<int, TDS2_halfedge_id_map<VB, FB> >
{
typedef typename CGAL::Triangulation_data_structure_2<VB,FB> TDS;
public:
typedef boost::readable_property_map_tag category;
typedef int value_type;
typedef int reference;
typedef CGAL::internal::T2_halfedge_descriptor<TDS> key_type;
typedef typename TDS::Face_handle face_descriptor;
TDS2_halfedge_id_map() { }
// Halfedge id is twice the edge id, and +0/+1 depending whether
// h.first is such that h.first < opposite(h).first --> different ids
value_type operator[](key_type h) const
{
const face_descriptor f1 = h.first;
const face_descriptor f2 = f1->neighbor(h.second);
if(f1->id() < f2->id())
return 2*(3 * f1->id() + h.second);
else
return 2*(3 * f2->id() + f2->index(f1)) + 1;
}
};
template <class VB, class FB>
class TDS2_edge_id_map
: public boost::put_get_helper<int, TDS2_edge_id_map<VB, FB> >
{
typedef typename CGAL::Triangulation_data_structure_2<VB,FB> TDS;
public:
typedef boost::readable_property_map_tag category;
typedef int value_type;
typedef int reference;
typedef CGAL::internal::T2_edge_descriptor<TDS> key_type;
typedef typename TDS::Face_handle Face_handle;
TDS2_edge_id_map() {}
value_type operator[](key_type h) const
{
const Face_handle f1 = h.first;
const Face_handle f2 = f1->neighbor(h.second);
if(f1->id() < f2->id())
return 3 * f1->id() + h.second;
else
return 3 * f2->id() + f2->index(f1);
}
};
template <class VB, class FB>
class TDS2_face_id_map
: public boost::put_get_helper<int, TDS2_face_id_map<VB, FB> >
{
typedef typename CGAL::Triangulation_data_structure_2<VB,FB> TDS;
public:
typedef boost::readable_property_map_tag category;
typedef int value_type;
typedef int reference;
typedef typename TDS::Face_handle key_type;
TDS2_face_id_map() { }
value_type operator[](key_type f) const { return f->id(); }
};
template <class VB, class FB, class Tag>
struct TDS2_property_map { };
template <class VB, class FB>
struct TDS2_property_map<VB, FB, boost::vertex_point_t>
{
typedef internal::TDS2_vertex_point_map<VB,FB> type;
typedef internal::TDS2_vertex_point_map<VB,FB> const_type;
};
template <class VB, class FB>
struct TDS2_property_map<VB, FB, boost::edge_weight_t>
{
typedef internal::TDS2_edge_weight_map<VB,FB> type;
typedef internal::TDS2_edge_weight_map<VB,FB> const_type;
};
template <class VB, class FB>
struct TDS2_property_map<VB, FB, boost::vertex_index_t>
{
typedef internal::TDS2_vertex_id_map<VB,FB> type;
typedef internal::TDS2_vertex_id_map<VB,FB> const_type;
};
template <class VB, class FB>
struct TDS2_property_map<VB, FB, boost::halfedge_index_t>
{
typedef internal::TDS2_vertex_id_map<VB,FB> type;
typedef internal::TDS2_vertex_id_map<VB,FB> const_type;
};
template <class VB, class FB>
struct TDS2_property_map<VB, FB, boost::edge_index_t>
{
typedef internal::TDS2_edge_id_map<VB,FB> type;
typedef internal::TDS2_edge_id_map<VB,FB> const_type;
};
template <class VB, class FB>
struct TDS2_property_map<VB, FB, boost::face_index_t>
{
typedef internal::TDS2_vertex_id_map<VB,FB> type;
typedef internal::TDS2_vertex_id_map<VB,FB> const_type;
};
} // end namespace internal
template <class VB, class FB >
struct graph_has_property<CGAL::Triangulation_data_structure_2<VB, FB>, boost::vertex_point_t>
: CGAL::Tag_true{};
template<class VB, class FB >
struct graph_has_property<CGAL::Triangulation_data_structure_2<VB, FB>, boost::edge_weight_t>
: CGAL::Tag_true{};
template<class VB, class FB >
struct graph_has_property<CGAL::Triangulation_data_structure_2<VB, FB>, boost::vertex_index_t>
: CGAL::Boolean_tag<
CGAL::internal::Has_member_id<
typename CGAL::Triangulation_data_structure_2<VB, FB>::Vertex
>::value
>
{};
template<class VB, class FB >
struct graph_has_property<CGAL::Triangulation_data_structure_2<VB, FB>, boost::halfedge_index_t>
: CGAL::Boolean_tag<
CGAL::internal::Has_member_id<
typename CGAL::Triangulation_data_structure_2<VB, FB>::Face
>::value
>
{};
template<class VB, class FB >
struct graph_has_property<CGAL::Triangulation_data_structure_2<VB, FB>, boost::edge_index_t>
: CGAL::Boolean_tag<
CGAL::internal::Has_member_id<
typename CGAL::Triangulation_data_structure_2<VB, FB>::Face
>::value
>
{};
template<class VB, class FB >
struct graph_has_property<CGAL::Triangulation_data_structure_2<VB, FB>, boost::face_index_t>
: CGAL::Boolean_tag<
CGAL::internal::Has_member_id<
typename CGAL::Triangulation_data_structure_2<VB, FB>::Face
>::value
>
{};
template <class VB, class FB>
inline internal::TDS2_vertex_point_map<VB,FB>
get(boost::vertex_point_t, const Triangulation_data_structure_2<VB,FB>&)
{
internal::TDS2_vertex_point_map<VB,FB> m;
return m;
}
template <class VB, class FB>
inline internal::TDS2_edge_weight_map<VB,FB>
get(boost::edge_weight_t, const Triangulation_data_structure_2<VB,FB>& g)
{
internal::TDS2_edge_weight_map<VB,FB> m(g);
return m;
}
template <class VB, class FB>
inline internal::TDS2_vertex_id_map<VB,FB>
get(boost::vertex_index_t, const Triangulation_data_structure_2<VB,FB>&)
{
internal::TDS2_vertex_id_map<VB,FB> m;
return m;
}
template <class VB, class FB>
inline internal::TDS2_halfedge_id_map<VB,FB>
get(boost::halfedge_index_t, const Triangulation_data_structure_2<VB,FB>&)
{
internal::TDS2_halfedge_id_map<VB,FB> m;
return m;
}
template <class VB, class FB>
inline internal::TDS2_edge_id_map<VB,FB>
get(boost::edge_index_t, const Triangulation_data_structure_2<VB,FB>&)
{
internal::TDS2_edge_id_map<VB,FB> m;
return m;
}
template <class VB, class FB>
inline internal::TDS2_face_id_map<VB,FB>
get(boost::face_index_t, const Triangulation_data_structure_2<VB,FB>&)
{
internal::TDS2_face_id_map<VB,FB> m;
return m;
}
} // namespace CGAL
namespace boost {
// g++ 'enumeral_type' in template unification not implemented workaround
template <class VB, class FB, class Tag>
struct property_map<CGAL::Triangulation_data_structure_2<VB,FB>, Tag>
{
typedef typename CGAL::internal::TDS2_property_map<VB, FB, Tag> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
// see struct property_map in Polyehdron for an explanation
template <class VB, class FB, class Tag>
struct property_map<const CGAL::Triangulation_data_structure_2<VB,FB>, Tag>
{
typedef typename CGAL::internal::TDS2_property_map<VB, FB, Tag> map_gen;
typedef typename map_gen::type type;
typedef typename map_gen::const_type const_type;
};
} // namespace boost
namespace CGAL {
template <class VB, class FB, class PropertyTag, class Key>
inline
typename boost::property_traits<
typename boost::property_map<Triangulation_data_structure_2<VB,FB>,PropertyTag>::const_type>::value_type
get(PropertyTag p, const Triangulation_data_structure_2<VB,FB>& g, const Key& key)
{
return get(get(p, g), key);
}
template <class VB, class FB, class PropertyTag, class Key,class Value>
inline void
put(PropertyTag p, Triangulation_data_structure_2<VB,FB>& g,
const Key& key, const Value& value)
{
typedef typename boost::property_map<Triangulation_data_structure_2<VB,FB>, PropertyTag>::type Map;
Map pmap = get(p, g);
put(pmap, key, value);
}
} // namespace CGAL
namespace boost {
// What are those needed for ???
template <typename VB, typename FB>
struct edge_property_type<CGAL::Triangulation_data_structure_2<VB,FB> > {
typedef void type;
};
template <typename VB, typename FB>
struct vertex_property_type<CGAL::Triangulation_data_structure_2<VB,FB> > {
typedef void type;
};
} // namespace boost
#endif /* CGAL_PROPERTIES_TRIANGULATION_DATA_STRUCTURE_2_H */

View File

@ -0,0 +1,30 @@
// Copyright (c) 2019 GeometryFactory (France). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
// Author(s) : Mael Rouxel-Labbé
#ifndef CGAL_PROPERTIES_TRIANGULATION_HIERARCHY_2_H
#define CGAL_PROPERTIES_TRIANGULATION_HIERARCHY_2_H
#include <CGAL/Triangulation_hierarchy_2.h>
#define CGAL_2D_TRIANGULATION_TEMPLATE_PARAMETERS typename Tr
#define CGAL_2D_TRIANGULATION CGAL::Triangulation_hierarchy_2<Tr>
#include <CGAL/boost/graph/internal/properties_2D_triangulation.h>
#endif /* CGAL_PROPERTIES_TRIANGULATION_HIERARCHY_2_H */

View File

@ -21,6 +21,7 @@ Number_types
Polygon
Profiling_tools
Property_map
Random_numbers
STL_Extension
Spatial_sorting
Stream_support