Merge remote-tracking branch 'cgal/master' into SLS-Weighted_skeleton-GF

This commit is contained in:
Mael Rouxel-Labbé 2023-02-14 12:26:50 +01:00
commit 68067c039f
183 changed files with 1663 additions and 1134 deletions

View File

@ -2,6 +2,7 @@ name: remove_labels
on: on:
pull_request_target: pull_request_target:
types: [synchronize] types: [synchronize]
workflow_dispatch:
jobs: jobs:
remove_label: remove_label:
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@ -66,7 +66,6 @@ jobs:
with: with:
repository: ${{ github.repository }} repository: ${{ github.repository }}
ref: refs/pull/${{ steps.get_pr_number.outputs.result }}/merge ref: refs/pull/${{ steps.get_pr_number.outputs.result }}/merge
token: ${{ secrets.PUSH_TO_CGAL_GITHUB_IO_TOKEN }}
fetch-depth: 2 fetch-depth: 2
- name: install dependencies - name: install dependencies
@ -74,7 +73,7 @@ jobs:
run: | run: |
set -x set -x
sudo apt-get update && sudo apt-get install -y graphviz ssh bibtex2html sudo apt-get update && sudo apt-get install -y graphviz ssh bibtex2html
sudo pip install lxml==4.6.3 sudo pip install lxml
sudo pip install pyquery sudo pip install pyquery
wget --no-verbose -O doxygen_exe https://cgal.geometryfactory.com/~cgaltest/doxygen_1_8_13_patched/doxygen wget --no-verbose -O doxygen_exe https://cgal.geometryfactory.com/~cgaltest/doxygen_1_8_13_patched/doxygen
sudo mv doxygen_exe /usr/bin/doxygen sudo mv doxygen_exe /usr/bin/doxygen

View File

@ -1,6 +1,6 @@
name: CMake Test Merge Branch name: CMake Test Merge Branch
on: [push, pull_request] on: [push, pull_request, workflow_dispatch]
permissions: permissions:
contents: read contents: read

View File

@ -1,6 +1,6 @@
name: CMake Testsuite name: CMake Testsuite
on: [push, pull_request] on: [push, pull_request, workflow_dispatch]
permissions: permissions:
contents: read contents: read

View File

@ -2,7 +2,7 @@ name: Documentation Removal
on: on:
pull_request_target: pull_request_target:
types: [closed, removed] types: [closed, removed, workflow_dispatch]
permissions: permissions:
contents: read contents: read

View File

@ -1,6 +1,6 @@
name: Test Polyhedron Demo name: Test Polyhedron Demo
on: [push, pull_request] on: [push, pull_request,workflow_dispatch]
permissions: permissions:
contents: read contents: read

View File

@ -3,6 +3,7 @@ name: Filter Testsuite
on: on:
issue_comment: issue_comment:
types: [created] types: [created]
workflow_dispatch:
permissions: {} permissions: {}
jobs: jobs:

View File

@ -2,7 +2,6 @@
// A face overlay of two arrangements with unbounded faces. // A face overlay of two arrangements with unbounded faces.
#include <string> #include <string>
#include <boost/lexical_cast.hpp>
#include <CGAL/basic.h> #include <CGAL/basic.h>
#include <CGAL/Arr_extended_dcel.h> #include <CGAL/Arr_extended_dcel.h>
@ -14,7 +13,7 @@
// Define a functor for creating a label from a character and an integer. // Define a functor for creating a label from a character and an integer.
struct Overlay_label { struct Overlay_label {
std::string operator()(char c, unsigned int i) const std::string operator()(char c, unsigned int i) const
{ return c + boost::lexical_cast<std::string>(i); } { return c + std::to_string(i); }
}; };
typedef CGAL::Arr_face_extended_dcel<Traits, char> Dcel_dlue; typedef CGAL::Arr_face_extended_dcel<Traits, char> Dcel_dlue;

View File

@ -153,7 +153,7 @@ public:
Dag_node* m_dag_node; //pointer to the search structure (DAG) node Dag_node* m_dag_node; //pointer to the search structure (DAG) node
/*! Initialize the trapezoid's neighbors. */ /*! Initialize the trapezoid's neighbors. */
CGAL_TD_INLINE void init_neighbours(Self* lb_ = 0, Self* lt_ = 0, CGAL_TD_INLINE void init_neighbors(Self* lb_ = 0, Self* lt_ = 0,
Self* rb_ = 0, Self* rt_ = 0) Self* rb_ = 0, Self* rt_ = 0)
{ {
set_lb(lb_); set_lb(lb_);
@ -161,6 +161,11 @@ public:
set_rb(rb_); set_rb(rb_);
set_rt(rt_); set_rt(rt_);
} }
/*! \copydoc init_neighbors
* \deprecated please use #init_neighbors */
CGAL_DEPRECATED CGAL_TD_INLINE void init_neighbours(Self* lb_ = 0, Self* lt_ = 0,
Self* rb_ = 0, Self* rt_ = 0)
{ init_neighbors(lb_, lt_, rb_, rt_); }
/*! Set the DAG node. */ /*! Set the DAG node. */
CGAL_TD_INLINE void set_dag_node(Dag_node* p) CGAL_TD_INLINE void set_dag_node(Dag_node* p)

View File

@ -145,10 +145,14 @@ public:
//Dag_node* m_dag_node; //pointer to the search structure (DAG) node //Dag_node* m_dag_node; //pointer to the search structure (DAG) node
/*! Initialize the trapezoid's neighbors. */ /*! Initialize the trapezoid's neighbors. */
inline void init_neighbours(boost::optional<Td_map_item&> next) inline void init_neighbors(boost::optional<Td_map_item&> next)
{ {
set_next((next) ? *next : Td_map_item(0)); set_next((next) ? *next : Td_map_item(0));
} }
/*! \copydoc init_neighbors
* \deprecated please use #init_neighbors */
CGAL_DEPRECATED inline void init_neighbours(boost::optional<Td_map_item&> next)
{ init_neighbors(next); }
/*! Set the DAG node. */ /*! Set the DAG node. */
CGAL_TD_INLINE void set_dag_node(Dag_node* p) CGAL_TD_INLINE void set_dag_node(Dag_node* p)

View File

@ -163,7 +163,7 @@ private:
//Dag_node* m_dag_node; //pointer to the search structure (DAG) node //Dag_node* m_dag_node; //pointer to the search structure (DAG) node
/*! Initialize the trapezoid's neighbors. */ /*! Initialize the trapezoid's neighbors. */
inline void init_neighbours(boost::optional<Td_map_item&> lb, boost::optional<Td_map_item&> lt, inline void init_neighbors(boost::optional<Td_map_item&> lb, boost::optional<Td_map_item&> lt,
boost::optional<Td_map_item&> rb, boost::optional<Td_map_item&> rt) boost::optional<Td_map_item&> rb, boost::optional<Td_map_item&> rt)
{ {
set_lb((lb) ? *lb : Td_map_item(0)); set_lb((lb) ? *lb : Td_map_item(0));
@ -171,6 +171,11 @@ private:
set_rb((rb) ? *rb : Td_map_item(0)); set_rb((rb) ? *rb : Td_map_item(0));
set_rt((rt) ? *rt : Td_map_item(0)); set_rt((rt) ? *rt : Td_map_item(0));
} }
/*! \copydoc init_neighbors
* \deprecated please use #init_neighbors */
CGAL_DEPRECATED inline void init_neighbours(boost::optional<Td_map_item&> lb, boost::optional<Td_map_item&> lt,
boost::optional<Td_map_item&> rb, boost::optional<Td_map_item&> rt)
{ init_neighbors(lb, lt, rb, rt); }
/*! Set the DAG node. */ /*! Set the DAG node. */
inline void set_dag_node(Dag_node* p) inline void set_dag_node(Dag_node* p)

View File

@ -72,9 +72,9 @@ split_trapezoid_by_vertex(Dag_node& split_node,
CGAL_warning(left_tr.is_on_left_boundary() == tr.is_on_left_boundary()); CGAL_warning(left_tr.is_on_left_boundary() == tr.is_on_left_boundary());
CGAL_warning(right_tr.is_on_right_boundary() == tr.is_on_right_boundary()); CGAL_warning(right_tr.is_on_right_boundary() == tr.is_on_right_boundary());
left_tr.init_neighbours(tr.lb(), tr.lt(), left_tr.init_neighbors(tr.lb(), tr.lt(),
right_node.get_data(), right_node.get_data()); right_node.get_data(), right_node.get_data());
right_tr.init_neighbours(left_node.get_data(), left_node.get_data(), right_tr.init_neighbors(left_node.get_data(), left_node.get_data(),
tr.rb(), tr.rt()); tr.rb(), tr.rt());
if (!traits->is_empty_item(tr.lb())) { if (!traits->is_empty_item(tr.lb())) {
Td_active_trapezoid& lb(boost::get<Td_active_trapezoid>(tr.lb())); Td_active_trapezoid& lb(boost::get<Td_active_trapezoid>(tr.lb()));
@ -109,10 +109,10 @@ split_trapezoid_by_vertex(Dag_node& split_node,
//CGAL_warning(left_e.is_on_left_boundary() == e.is_on_left_boundary()); //CGAL_warning(left_e.is_on_left_boundary() == e.is_on_left_boundary());
//CGAL_warning(right_e.is_on_right_boundary() == e.is_on_right_boundary()); //CGAL_warning(right_e.is_on_right_boundary() == e.is_on_right_boundary());
left_e.init_neighbours(boost::none); left_e.init_neighbors(boost::none);
//left_e.init_neighbours(e.lb(),e.lt(),Td_map_item(),right_node.get_data()); //left_e.init_neighbors(e.lb(),e.lt(),Td_map_item(),right_node.get_data());
right_e.init_neighbours(e.next()); right_e.init_neighbors(e.next());
//right_e.init_neighbours(left_node.get_data(),left_node.get_data(),e.rb(),e.rt()); //right_e.init_neighbors(left_node.get_data(),left_node.get_data(),e.rb(),e.rt());
} }
// left and right are set to the point itself, // left and right are set to the point itself,
@ -307,8 +307,8 @@ split_trapezoid_by_halfedge(Dag_node& split_node,
Td_active_trapezoid& top = Td_active_trapezoid& top =
boost::get<Td_active_trapezoid>(top_node.get_data()); boost::get<Td_active_trapezoid>(top_node.get_data());
top.init_neighbours(prev_top_tr, split_tr.lt(), boost::none , split_tr.rt()); top.init_neighbors(prev_top_tr, split_tr.lt(), boost::none , split_tr.rt());
bottom.init_neighbours(split_tr.lb(), prev_bottom_tr, split_tr.rb(), bottom.init_neighbors(split_tr.lb(), prev_bottom_tr, split_tr.rb(),
boost::none); boost::none);
if (!traits->is_empty_item(prev_bottom_tr)) { if (!traits->is_empty_item(prev_bottom_tr)) {
@ -2340,7 +2340,7 @@ vertical_ray_shoot(const Point & p,Locate_type & lt,
// } // }
// else // new_left_t is leftmost representative for he // else // new_left_t is leftmost representative for he
// { // {
// //set_neighbours_after_split_halfedge_update (new_left_t, t1, he1, he2); //MICHAL: this method does nothing // //set_neighbors_after_split_halfedge_update (new_left_t, t1, he1, he2); //MICHAL: this method does nothing
// } // }
// if (t1.rt()==&old_t) t1.set_rt(&new_left_t); // if (t1.rt()==&old_t) t1.set_rt(&new_left_t);
// if (t1.lb()==&old_t) t1.set_lb(&new_left_t); // if (t1.lb()==&old_t) t1.set_lb(&new_left_t);
@ -2366,7 +2366,7 @@ vertical_ray_shoot(const Point & p,Locate_type & lt,
// } // }
// else // new_right_t is rightmost representative for te // else // new_right_t is rightmost representative for te
// { // {
// //set_neighbours_after_split_halfedge_update (new_right_t,t2,he1, he2,false); //MICHAL: this method does nothing // //set_neighbors_after_split_halfedge_update (new_right_t,t2,he1, he2,false); //MICHAL: this method does nothing
// } // }
// if (t2.rt()==&old_t) t2.set_rt(&new_right_t); // if (t2.rt()==&old_t) t2.set_rt(&new_right_t);
// if (t2.lb()==&old_t) t2.set_lb(&new_right_t); // if (t2.lb()==&old_t) t2.set_lb(&new_right_t);

View File

@ -215,16 +215,16 @@ is_in_face(const Face* f, const Point_2& p, const Vertex* v) const
/*! We identify 2 main cases: /*! We identify 2 main cases:
* 1. The vertical ray intersects the boundary at a halfedge. In this * 1. The vertical ray intersects the boundary at a halfedge. In this
* case the x-possition of p is strictly larger than the x-possition of * case the x-position of p is strictly larger than the x-position of
* the current-curve source, and strictly smaller than x-possition of * the current-curve source, and strictly smaller than x-position of
* the current-curve target, or vice versa. * the current-curve target, or vice versa.
* 2. The vertical ray intersects the boundary at a vertex. In this case: * 2. The vertical ray intersects the boundary at a vertex. In this case:
* a. the x-possition of p is strictly smaller than the x-position of the * a. the x-position of p is strictly smaller than the x-position of the
* current-curve source, and equal to the x-position of the current-curve * current-curve source, and equal to the x-position of the current-curve
* target, and * target, and
* b. the x-possition of p is equal to the x-position of the next-curve * b. the x-position of p is equal to the x-position of the next-curve
* source (not counting vertical curves in between), and strictly larger * source (not counting vertical curves in between), and strictly larger
* than the x-possition of the next-curve target, or vice verase (that is, * than the x-position of the next-curve target, or vice verase (that is,
* the "smaller" and "larger" interchanged). * the "smaller" and "larger" interchanged).
*/ */

View File

@ -1065,7 +1065,7 @@ void draw_lump(std::vector< Coord_2 >& rev_points, int& last_x,
if(set_ready) if(set_ready)
ready = true; ready = true;
if(!test_neighbourhood(pix, back_dir, new_dir)) { if(!test_neighborhood(pix, back_dir, new_dir)) {
ux = pix.x; ux = pix.x;
uy = pix.y; uy = pix.y;
if(witness == pix) { // witness subpixel is a pixel itself if(witness == pix) { // witness subpixel is a pixel itself
@ -1095,7 +1095,7 @@ void draw_lump(std::vector< Coord_2 >& rev_points, int& last_x,
stored_prev = prev_pix; stored_prev = prev_pix;
} }
if(!test_neighbourhood(pix, back_dir, new_dir)) { if(!test_neighborhood(pix, back_dir, new_dir)) {
if(stored_dir != -1) { if(stored_dir != -1) {
pix = stored_pix; pix = stored_pix;
prev_pix = stored_prev; prev_pix = stored_prev;
@ -1257,7 +1257,7 @@ bool subdivide(Pixel_2& pix, int back_dir, int& new_dir) {
pix.sub_y = (pix.sub_y<<1) + (idx>>1); pix.sub_y = (pix.sub_y<<1) + (idx>>1);
//Gfx_DETAILED_OUT("subpixel index: " << idx << " (" << pix.sub_x << "; " //Gfx_DETAILED_OUT("subpixel index: " << idx << " (" << pix.sub_x << "; "
// << pix.sub_y << ")" << std::endl); // << pix.sub_y << ")" << std::endl);
if(!test_neighbourhood(pix, back_dir, new_dir)) if(!test_neighborhood(pix, back_dir, new_dir))
return subdivide(pix,back_dir,new_dir); return subdivide(pix,back_dir,new_dir);
//Gfx_DETAILED_OUT("new direction found: " << new_dir << " at a pixel:" << //Gfx_DETAILED_OUT("new direction found: " << new_dir << " at a pixel:" <<
//pix << std::endl); //pix << std::endl);
@ -1313,7 +1313,7 @@ bool get_seed_point(const Rational& seed, Pixel_2& start, int *dir,
<< start.level << std::endl; << start.level << std::endl;
throw internal::Insufficient_rasterize_precision_exception(); throw internal::Insufficient_rasterize_precision_exception();
} }
//dump_neighbourhood(start); //dump_neighborhood(start);
if(limit(engine.pixel_w/NT(lvl))||limit(engine.pixel_h/NT(lvl))) { if(limit(engine.pixel_w/NT(lvl))||limit(engine.pixel_h/NT(lvl))) {
std::cerr << "get_seed_point: too small subpixel size: " << std::cerr << "get_seed_point: too small subpixel size: " <<
@ -1425,7 +1425,7 @@ bool test_pixel(const Pixel_2& pix, int *dir, int *b_taken, bool& b_coincide)
/* /*
Gfx_OUT("test pixel: " << pix << "--------------------------------\n"); Gfx_OUT("test pixel: " << pix << "--------------------------------\n");
dump_neighbourhood(pix); dump_neighborhood(pix);
Gfx_OUT("----------------------------------------------\n\n");*/ Gfx_OUT("----------------------------------------------\n\n");*/
b_coincide = false; b_coincide = false;
@ -1913,7 +1913,7 @@ inline void get_polynomials(int var, Stripe& stripe) {
* if \c CGAL_CKVA_RENDER_WITH_REFINEMENT is set, in case of success \c pix * if \c CGAL_CKVA_RENDER_WITH_REFINEMENT is set, in case of success \c pix
* receives double approximations of intersection point * receives double approximations of intersection point
*/ */
bool test_neighbourhood(Pixel_2& pix, int dir, int& new_dir) bool test_neighborhood(Pixel_2& pix, int dir, int& new_dir)
{ {
NT lvl = NT(one << pix.level); NT lvl = NT(one << pix.level);
NT inv = NT(1.0) / lvl; NT inv = NT(1.0) / lvl;
@ -2258,6 +2258,11 @@ Lexit:
pix.yv = CGAL::to_double(engine.y_min + y*engine.pixel_h); pix.yv = CGAL::to_double(engine.y_min + y*engine.pixel_h);
return ret; return ret;
} }
/*! \copydoc test_neighborhood
* \deprecated please use #test_neighborhood */
CGAL_DEPRECATED bool test_neighbourhood(Pixel_2& pix, int dir, int& new_dir)
{ return test_neighborhood(pix, new_dir); }
#endif // CGAL_CKVA_RENDER_WITH_REFINEMENT #endif // CGAL_CKVA_RENDER_WITH_REFINEMENT
//! \brief returns whether a polynomial has zero over an interval, //! \brief returns whether a polynomial has zero over an interval,
@ -2585,7 +2590,7 @@ inline bool is_isolated_pixel(const Pixel_2& /* pix */) {
// DEBUG ONLY // DEBUG ONLY
#ifdef Gfx_USE_OUT #ifdef Gfx_USE_OUT
void dump_neighbourhood(const Pixel_2& pix) { void dump_neighborhood(const Pixel_2& pix) {
CGAL::IO::set_mode(std::cerr, CGAL::IO::PRETTY); CGAL::IO::set_mode(std::cerr, CGAL::IO::PRETTY);
CGAL::IO::set_mode(std::cout, CGAL::IO::PRETTY); CGAL::IO::set_mode(std::cout, CGAL::IO::PRETTY);
@ -2764,8 +2769,10 @@ void dump_neighbourhood(const Pixel_2& pix) {
Gfx_OUT("sign change at segment 2" << std::endl); Gfx_OUT("sign change at segment 2" << std::endl);
} }
#else #else
void dump_neighbourhood(const Pixel_2&) { } void dump_neighborhood(const Pixel_2&) { }
#endif // Gfx_USE_OUT #endif // Gfx_USE_OUT
CGAL_DEPRECATED void dump_neighbourhood(const Pixel_2& pix)
{ dump_neighborhood(pix); }
//!@} //!@}
}; // class Curve_renderer_2<> }; // class Curve_renderer_2<>

View File

@ -19,21 +19,32 @@
#include <CGAL/Random.h> #include <CGAL/Random.h>
#include <CGAL/boost/graph/helpers.h> #include <CGAL/boost/graph/helpers.h>
namespace CGAL namespace CGAL {
{
// Default color functor; user can change it to have its own face color // Default color functor; user can change it to have its own face color
struct DefaultColorFunctorFaceGraph struct DefaultColorFunctorFaceGraph
{ {
template<typename Graph> template<typename Graph>
CGAL::IO::Color operator()(const Graph&, CGAL::IO::Color operator()(const Graph& /*g*/,
typename boost::graph_traits<Graph>::face_descriptor fh) const typename boost::graph_traits<Graph>::face_descriptor /*f*/) const
{ {
if (fh==boost::graph_traits<Graph>::null_face()) // use to get the mono color
return CGAL::IO::Color(100, 125, 200); // R G B between 0-255
return get_random_color(CGAL::get_default_random()); return get_random_color(CGAL::get_default_random());
} }
// edges and vertices are black by default
template<typename Graph>
CGAL::IO::Color operator()(const Graph& /*g*/,
typename boost::graph_traits<Graph>::edge_descriptor /*e*/) const
{
return IO::black();
}
template<typename Graph>
CGAL::IO::Color operator()(const Graph& /*g*/,
typename boost::graph_traits<Graph>::vertex_descriptor /*v*/) const
{
return IO::black();
}
}; };
class SimpleFaceGraphViewerQt : public Basic_viewer_qt class SimpleFaceGraphViewerQt : public Basic_viewer_qt
@ -48,28 +59,28 @@ public:
} }
/// Construct the viewer. /// Construct the viewer.
/// @param amesh the surface mesh to view /// @param g the face graph to view
/// @param title the title of the window /// @param title the title of the window
/// @param anofaces if true, do not draw faces (faces are not computed; this can be /// @param anofaces if true, do not draw faces (faces are not computed; this can be
/// useful for very big object where this time could be long) /// useful for very big objects where this time could be long)
template <typename SM> template <typename Graph>
SimpleFaceGraphViewerQt(QWidget* parent, SimpleFaceGraphViewerQt(QWidget* parent,
const SM& amesh, const Graph& g,
const char* title="Basic Surface_mesh Viewer", const char* title="Basic Face Graph Viewer",
bool anofaces=false) : bool anofaces=false) :
SimpleFaceGraphViewerQt(parent, amesh, title, anofaces, DefaultColorFunctorFaceGraph()) SimpleFaceGraphViewerQt(parent, g, title, anofaces, DefaultColorFunctorFaceGraph())
{ {
} }
template <typename SM, typename ColorFunctor> template <typename Graph, typename ColorFunctor>
SimpleFaceGraphViewerQt(QWidget* parent, SimpleFaceGraphViewerQt(QWidget* parent,
const SM& amesh, const Graph& g,
const char* title, const char* title,
bool anofaces, bool anofaces,
ColorFunctor fcolor) : ColorFunctor fcolor) :
// First draw: no vertex; edges, faces; mono-color; inverse normal // First draw: no vertex; edges, faces; mono-color; inverse normal
Base(parent, title, false, true, true, true, false), Base(parent, title, false, true, true, true, false),
m_compute_elements_impl(compute_elements_functor(amesh, anofaces, fcolor)) m_compute_elements_impl(compute_elements_functor(g, anofaces, fcolor))
{ {
} }
@ -82,43 +93,42 @@ public:
m_compute_elements_impl(); m_compute_elements_impl();
} }
template <typename SM, typename ColorFunctor> template <typename Graph, typename ColorFunctor>
void set_face_graph(const SM& amesh, void set_face_graph(const Graph& g,
bool anofaces, bool anofaces,
ColorFunctor fcolor) { ColorFunctor fcolor) {
m_compute_elements_impl = compute_elements_functor(amesh, anofaces, fcolor); m_compute_elements_impl = compute_elements_functor(g, anofaces, fcolor);
} }
template <typename SM, typename ColorFunctor> template <typename Graph, typename ColorFunctor>
void set_face_graph(const SM& amesh, void set_face_graph(const Graph& g,
bool anofaces=false) { bool anofaces=false) {
set_mesh(amesh, anofaces, DefaultColorFunctorFaceGraph()); set_mesh(g, anofaces, DefaultColorFunctorFaceGraph());
} }
protected: protected:
template <typename SM, typename ColorFunctor> template <typename Graph, typename ColorFunctor>
std::function<void()> std::function<void()>
compute_elements_functor(const SM& sm, compute_elements_functor(const Graph& g,
bool anofaces, bool anofaces,
ColorFunctor fcolor) ColorFunctor fcolor)
{ {
using Point = using Point = typename boost::property_map_value<Graph, CGAL::vertex_point_t>::type;
typename boost::property_map_value<SM, CGAL::vertex_point_t>::type;
using Kernel = typename CGAL::Kernel_traits<Point>::Kernel; using Kernel = typename CGAL::Kernel_traits<Point>::Kernel;
using Vector = typename Kernel::Vector_3; using Vector = typename Kernel::Vector_3;
auto vnormals = get(CGAL::dynamic_vertex_property_t<Vector>(), sm); auto vnormals = get(CGAL::dynamic_vertex_property_t<Vector>(), g);
auto point_pmap = get(CGAL::vertex_point, sm); auto point_pmap = get(CGAL::vertex_point, g);
for (auto v : vertices(sm)) for (auto v : vertices(g))
{ {
Vector n(NULL_VECTOR); Vector n(NULL_VECTOR);
int i=0; int i=0;
for (auto h : halfedges_around_target(halfedge(v, sm), sm)) for (auto h : halfedges_around_target(halfedge(v, g), g))
{ {
if (!is_border(h, sm)) if (!is_border(h, g))
{ {
Vector ni = CGAL::cross_product( Vector ni = CGAL::cross_product(
Vector(get(point_pmap, source(h, sm)), get(point_pmap, target(h, sm))), Vector(get(point_pmap, source(h, g)), get(point_pmap, target(h, g))),
Vector(get(point_pmap, target(h, sm)), get(point_pmap, target(next(h, sm), sm)))); Vector(get(point_pmap, target(h, g)), get(point_pmap, target(next(h, g), g))));
if (ni != NULL_VECTOR) if (ni != NULL_VECTOR)
{ {
n+=ni; n+=ni;
@ -131,41 +141,41 @@ protected:
// This function return a lambda expression, type-erased in a // This function return a lambda expression, type-erased in a
// `std::function<void()>` object. // `std::function<void()>` object.
return [this, &sm, vnormals, anofaces, fcolor, point_pmap]() return [this, &g, vnormals, anofaces, fcolor, point_pmap]()
{ {
this->clear(); this->clear();
if (!anofaces) if (!anofaces)
{ {
for (auto fh: faces(sm)) for (auto fh: faces(g))
{ {
if (fh!=boost::graph_traits<SM>::null_face()) const CGAL::IO::Color& c = fcolor(g, fh);
{
CGAL::IO::Color c=fcolor(sm, fh);
face_begin(c); face_begin(c);
auto hd=halfedge(fh, sm); auto hd=halfedge(fh, g);
const auto first_hd = hd; const auto first_hd = hd;
do do
{ {
auto v = source(hd, sm); auto v = source(hd, g);
add_point_in_face(get(point_pmap, v), get(vnormals, v)); add_point_in_face(get(point_pmap, v), get(vnormals, v));
hd=next(hd, sm); hd=next(hd, g);
} }
while(hd!=first_hd); while(hd!=first_hd);
face_end(); face_end();
} }
} }
for (auto e: edges(g))
{
const CGAL::IO::Color& c = fcolor(g, e);
add_segment(get(point_pmap, source(halfedge(e, g), g)),
get(point_pmap, target(halfedge(e, g), g)),
c);
} }
for (auto e: edges(sm)) for (auto v: vertices(g))
{ {
add_segment(get(point_pmap, source(halfedge(e, sm), sm)), const CGAL::IO::Color& c = fcolor(g, v);
get(point_pmap, target(halfedge(e, sm), sm))); this->add_point(get(point_pmap, v), c);
}
for (auto v: vertices(sm))
{
this->add_point(get(point_pmap, v));
} }
}; };
} }

View File

@ -1,4 +1,4 @@
@INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS} @INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS}
PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - CGAL Ipelets" PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - CGAL Ipelets"
EXAMPLE_PATH += ${CGAL_PACKAGE_DIR}/demo EXAMPLE_PATH = ${CGAL_PACKAGE_DIR}/demo

View File

@ -1,4 +1,3 @@
/*! /*!
\example CGAL_ipelets/test_grabbers.cpp
\example CGAL_ipelets/simple_triangulation.cpp \example CGAL_ipelets/simple_triangulation.cpp
*/ */

View File

@ -2,7 +2,7 @@
# This is the CMake script for compiling a CGAL application. # This is the CMake script for compiling a CGAL application.
cmake_minimum_required(VERSION 3.1...3.23) cmake_minimum_required(VERSION 3.1...3.23)
project(CGAL_ipelets_Examples) project(CGAL_ipelets_Tests)
find_package(CGAL REQUIRED) find_package(CGAL REQUIRED)

View File

@ -140,7 +140,7 @@ int main (int argc, char** argv)
classifier.save_configuration(fconfig); classifier.save_configuration(fconfig);
// Write result // Write result
std::ofstream f ("classification.ply"); std::ofstream f ("classification_ethz_random_forest.ply");
f.precision(18); f.precision(18);
f << pts; f << pts;

View File

@ -128,7 +128,7 @@ int main (int argc, char** argv)
} }
// Write result // Write result
std::ofstream f ("classification.ply"); std::ofstream f ("classification_opencv_random_forest.ply");
f.precision(18); f.precision(18);
f << pts; f << pts;

View File

@ -473,7 +473,8 @@ int main (int argc, char** argv)
// Fill all holes except the bigest (which is the outer hull of the mesh) // Fill all holes except the bigest (which is the outer hull of the mesh)
for (Mesh::Halfedge_index hi : holes) for (Mesh::Halfedge_index hi : holes)
if (hi != outer_hull) if (hi != outer_hull)
CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole (dtm_mesh, hi); CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole
(dtm_mesh, hi, CGAL::parameters::fairing_continuity(0));
// Save DTM with holes filled // Save DTM with holes filled
std::ofstream dtm_filled_ofile ("dtm_filled.ply", std::ios_base::binary); std::ofstream dtm_filled_ofile ("dtm_filled.ply", std::ios_base::binary);
@ -735,7 +736,7 @@ int main (int argc, char** argv)
points.range(label_map)).mean_intersection_over_union() << std::endl; points.range(label_map)).mean_intersection_over_union() << std::endl;
// Save the classified point set // Save the classified point set
std::ofstream classified_ofile ("classified.ply"); std::ofstream classified_ofile ("classification_gis_tutorial.ply");
CGAL::IO::set_binary_mode (classified_ofile); CGAL::IO::set_binary_mode (classified_ofile);
classified_ofile << points; classified_ofile << points;
classified_ofile.close(); classified_ofile.close();

View File

@ -4,7 +4,6 @@
#include <iterator> #include <iterator>
#include <string> #include <string>
#include <vector> #include <vector>
#include <boost/lexical_cast.hpp>
#include <CGAL/Exact_predicates_exact_constructions_kernel_with_root_of.h> #include <CGAL/Exact_predicates_exact_constructions_kernel_with_root_of.h>
#include <CGAL/Construct_theta_graph_2.h> #include <CGAL/Construct_theta_graph_2.h>
#include <CGAL/gnuplot_output_2.h> #include <CGAL/gnuplot_output_2.h>
@ -79,7 +78,7 @@ int main(int argc, char ** argv)
// obtain the number of vertices in the constructed graph // obtain the number of vertices in the constructed graph
boost::graph_traits<Graph>::vertices_size_type n = boost::num_vertices(g); boost::graph_traits<Graph>::vertices_size_type n = boost::num_vertices(g);
// generate gnuplot files for plotting this graph // generate gnuplot files for plotting this graph
std::string file_prefix = "t" + boost::lexical_cast<std::string>(k) + "n" + boost::lexical_cast<std::string>(n); std::string file_prefix = "t" + std::to_string(k) + "n" + std::to_string(n);
CGAL::gnuplot_output_2(g, file_prefix); CGAL::gnuplot_output_2(g, file_prefix);
return 0; return 0;

View File

@ -10,7 +10,6 @@
#include <iterator> #include <iterator>
#include <string> #include <string>
#include <vector> #include <vector>
#include <boost/lexical_cast.hpp>
#include <CGAL/Exact_predicates_exact_constructions_kernel_with_root_of.h> #include <CGAL/Exact_predicates_exact_constructions_kernel_with_root_of.h>
#include <CGAL/Construct_theta_graph_2.h> #include <CGAL/Construct_theta_graph_2.h>
#include <CGAL/gnuplot_output_2.h> #include <CGAL/gnuplot_output_2.h>
@ -70,7 +69,7 @@ int main(int argc, char ** argv)
// obtain the number of vertices in the constructed graph // obtain the number of vertices in the constructed graph
boost::graph_traits<Graph>::vertices_size_type n = boost::num_vertices(g); boost::graph_traits<Graph>::vertices_size_type n = boost::num_vertices(g);
// generate gnuplot files for plotting this graph // generate gnuplot files for plotting this graph
std::string file_prefix = "t" + boost::lexical_cast<std::string>(k) + "n" + boost::lexical_cast<std::string>(n); std::string file_prefix = "t" + std::to_string(k) + "n" + std::to_string(n);
CGAL::gnuplot_output_2(g, file_prefix); CGAL::gnuplot_output_2(g, file_prefix);
return 0; return 0;

View File

@ -11,7 +11,6 @@
#include <iterator> #include <iterator>
#include <string> #include <string>
#include <vector> #include <vector>
#include <boost/lexical_cast.hpp>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h> #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Construct_theta_graph_2.h> #include <CGAL/Construct_theta_graph_2.h>
#include <CGAL/gnuplot_output_2.h> #include <CGAL/gnuplot_output_2.h>
@ -71,7 +70,7 @@ int main(int argc, char ** argv)
// obtain the number of vertices in the constructed graph // obtain the number of vertices in the constructed graph
boost::graph_traits<Graph>::vertices_size_type n = boost::num_vertices(g); boost::graph_traits<Graph>::vertices_size_type n = boost::num_vertices(g);
// generate gnuplot files for plotting this graph // generate gnuplot files for plotting this graph
std::string file_prefix = "t" + boost::lexical_cast<std::string>(k) + "n" + boost::lexical_cast<std::string>(n); std::string file_prefix = "t" + std::to_string(k) + "n" + std::to_string(n);
CGAL::gnuplot_output_2(g, file_prefix); CGAL::gnuplot_output_2(g, file_prefix);
return 0; return 0;

View File

@ -12,7 +12,6 @@
#include <iterator> #include <iterator>
#include <string> #include <string>
#include <vector> #include <vector>
#include <boost/lexical_cast.hpp>
#include <CGAL/Exact_predicates_exact_constructions_kernel_with_root_of.h> #include <CGAL/Exact_predicates_exact_constructions_kernel_with_root_of.h>
#include <CGAL/Construct_yao_graph_2.h> #include <CGAL/Construct_yao_graph_2.h>
#include <CGAL/gnuplot_output_2.h> #include <CGAL/gnuplot_output_2.h>
@ -72,7 +71,7 @@ int main(int argc, char ** argv)
boost::graph_traits<Graph>::vertices_size_type n = boost::num_vertices(g); boost::graph_traits<Graph>::vertices_size_type n = boost::num_vertices(g);
// generate gnuplot files for plotting this graph // generate gnuplot files for plotting this graph
std::string fileprefix = "y" + boost::lexical_cast<std::string>(k) + "n" + boost::lexical_cast<std::string>(n); std::string fileprefix = "y" + std::to_string(k) + "n" + std::to_string(n);
CGAL::gnuplot_output_2(g, fileprefix); CGAL::gnuplot_output_2(g, fileprefix);
return 0; return 0;

View File

@ -12,7 +12,6 @@
#include <iterator> #include <iterator>
#include <string> #include <string>
#include <vector> #include <vector>
#include <boost/lexical_cast.hpp>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h> #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Construct_yao_graph_2.h> #include <CGAL/Construct_yao_graph_2.h>
#include <CGAL/gnuplot_output_2.h> #include <CGAL/gnuplot_output_2.h>
@ -72,7 +71,7 @@ int main(int argc, char ** argv)
boost::graph_traits<Graph>::vertices_size_type n = boost::num_vertices(g); boost::graph_traits<Graph>::vertices_size_type n = boost::num_vertices(g);
// generate gnuplot files for plotting this graph // generate gnuplot files for plotting this graph
std::string fileprefix = "y" + boost::lexical_cast<std::string>(k) + "n" + boost::lexical_cast<std::string>(n); std::string fileprefix = "y" + std::to_string(k) + "n" + std::to_string(n);
CGAL::gnuplot_output_2(g, fileprefix); CGAL::gnuplot_output_2(g, fileprefix);
return 0; return 0;

View File

@ -17,6 +17,7 @@
#include <CGAL/Nef_3/SNC_decorator.h> #include <CGAL/Nef_3/SNC_decorator.h>
#include <CGAL/Nef_3/SNC_external_structure.h>
#include <CGAL/Nef_3/SNC_intersection.h> #include <CGAL/Nef_3/SNC_intersection.h>
#undef CGAL_NEF_DEBUG #undef CGAL_NEF_DEBUG

View File

@ -17,6 +17,7 @@
#include <CGAL/Modifier_base.h> #include <CGAL/Modifier_base.h>
#include <CGAL/Nef_3/SNC_decorator.h> #include <CGAL/Nef_3/SNC_decorator.h>
#include <CGAL/Nef_3/SNC_point_locator.h>
#include <CGAL/Nef_3/SNC_intersection.h> #include <CGAL/Nef_3/SNC_intersection.h>
#include <CGAL/Convex_decomposition_3/SM_walls.h> #include <CGAL/Convex_decomposition_3/SM_walls.h>

View File

@ -14,8 +14,9 @@
#include <CGAL/license/Convex_decomposition_3.h> #include <CGAL/license/Convex_decomposition_3.h>
#include <CGAL/Modifier_base.h>
#include <CGAL/Nef_3/SNC_decorator.h> #include <CGAL/Nef_3/SNC_decorator.h>
#include <CGAL/Nef_3/SNC_point_locator.h>
#include <CGAL/Convex_decomposition_3/SM_walls.h> #include <CGAL/Convex_decomposition_3/SM_walls.h>
namespace CGAL { namespace CGAL {

View File

@ -14,6 +14,8 @@
#include <CGAL/license/Convex_decomposition_3.h> #include <CGAL/license/Convex_decomposition_3.h>
#include <CGAL/Nef_S2/SM_decorator.h>
#include <CGAL/Nef_S2/SM_point_locator.h>
#undef CGAL_NEF_DEBUG #undef CGAL_NEF_DEBUG
#define CGAL_NEF_DEBUG 227 #define CGAL_NEF_DEBUG 227

View File

@ -14,10 +14,12 @@
#include <CGAL/license/Convex_decomposition_3.h> #include <CGAL/license/Convex_decomposition_3.h>
#include <CGAL/Modifier_base.h>
#include <CGAL/Nef_3/SNC_decorator.h> #include <CGAL/Nef_3/SNC_decorator.h>
#include <CGAL/Nef_3/SNC_point_locator.h>
#include <CGAL/Nef_3/SNC_intersection.h> #include <CGAL/Nef_3/SNC_intersection.h>
#include <CGAL/Nef_S2/Normalizing.h> #include <CGAL/Nef_S2/Normalizing.h>
#include <CGAL/Convex_decomposition_3/Ray_hit_generator.h>
#include <CGAL/Convex_decomposition_3/SM_walls.h> #include <CGAL/Convex_decomposition_3/SM_walls.h>
#undef CGAL_NEF_DEBUG #undef CGAL_NEF_DEBUG

View File

@ -14,10 +14,12 @@
#include <CGAL/license/Convex_decomposition_3.h> #include <CGAL/license/Convex_decomposition_3.h>
#include <CGAL/Modifier_base.h>
#include <CGAL/Nef_3/SNC_decorator.h> #include <CGAL/Nef_3/SNC_decorator.h>
#include <CGAL/Nef_3/SNC_point_locator.h>
#include <CGAL/Nef_3/SNC_intersection.h> #include <CGAL/Nef_3/SNC_intersection.h>
#include <CGAL/Nef_S2/Normalizing.h> #include <CGAL/Nef_S2/Normalizing.h>
#include <CGAL/Convex_decomposition_3/Ray_hit_generator.h>
#include <CGAL/Convex_decomposition_3/SM_walls.h> #include <CGAL/Convex_decomposition_3/SM_walls.h>
#undef CGAL_NEF_DEBUG #undef CGAL_NEF_DEBUG

View File

@ -14,8 +14,9 @@
#include <CGAL/license/Convex_decomposition_3.h> #include <CGAL/license/Convex_decomposition_3.h>
#include <CGAL/Modifier_base.h>
#include <CGAL/Nef_3/SNC_decorator.h> #include <CGAL/Nef_3/SNC_decorator.h>
#include <CGAL/Convex_decomposition_3/is_reflex_sedge.h>
#include <CGAL/Convex_decomposition_3/Single_wall_creator3.h> #include <CGAL/Convex_decomposition_3/Single_wall_creator3.h>
#include <CGAL/Convex_decomposition_3/External_structure_builder.h> #include <CGAL/Convex_decomposition_3/External_structure_builder.h>

View File

@ -14,6 +14,8 @@
#include <CGAL/license/Convex_decomposition_3.h> #include <CGAL/license/Convex_decomposition_3.h>
#include <CGAL/enum.h>
#include <CGAL/Origin.h>
#undef CGAL_NEF_DEBUG #undef CGAL_NEF_DEBUG
#define CGAL_NEF_DEBUG 239 #define CGAL_NEF_DEBUG 239

View File

@ -143,6 +143,10 @@ check whether a given sequence of 2D points forms a (counter)clockwise strongly
convex polygon. These are used in postcondition convex polygon. These are used in postcondition
testing of the two-dimensional convex hull functions. testing of the two-dimensional convex hull functions.
In case you want to keep collinear points you can use the 2D Delaunay triangulation as
in the following example. This sequence is then <em>not</em> strongly convex.
\cgalExample{Convex_hull_2/ch_delaunay_2.cpp}
*/ */
} /* namespace CGAL */ } /* namespace CGAL */

View File

@ -6,4 +6,5 @@
\example Convex_hull_2/ch_timing.cpp \example Convex_hull_2/ch_timing.cpp
\example Convex_hull_2/iostream_convex_hull_2.cpp \example Convex_hull_2/iostream_convex_hull_2.cpp
\example Convex_hull_2/vector_convex_hull_2.cpp \example Convex_hull_2/vector_convex_hull_2.cpp
\example Convex_hull_2/ch_delaunay_2.cpp
*/ */

View File

@ -0,0 +1,27 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <list>
#include <iostream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point_2;
typedef CGAL::Delaunay_triangulation_2<K> Delaunay_triangulation_2;
int main()
{
std::vector<Point_2> input = { Point_2(0, 0), Point_2(1,1), Point_2(2,0), Point_2(2,2), Point_2(1,2), Point_2(0,2) };
Delaunay_triangulation_2 dt(input.begin(), input.end());
std::list<Point_2> result;
Delaunay_triangulation_2::Vertex_circulator vc = dt.incident_vertices(dt.infinite_vertex()), done(vc);
do{
std ::cout << vc->point() << std::endl;
// push_front in order to obtain the counterclockwise sequence
result.push_front(vc->point());
++vc;
}while(vc != done);
return 0;
}

View File

@ -27,9 +27,5 @@ int main()
CGAL::ch__batch_test(cch_H_gmp); CGAL::ch__batch_test(cch_H_gmp);
#endif #endif
CGAL::Convex_hull_constructive_traits_2< CGAL::Homogeneous<double> > cch_H_double;
std::cout << "Homogeneous<double>:" << std::endl;
CGAL::ch__batch_test(cch_H_double);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -25,9 +25,5 @@ int main()
CGAL::ch__batch_test(ch_C_Qgmp); CGAL::ch__batch_test(ch_C_Qgmp);
#endif #endif
CGAL::Cartesian<double> ch_C_double;
std::cout << "Cartesian<double>:" << std::endl;
CGAL::ch__batch_test(ch_C_double);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -25,9 +25,5 @@ int main()
CGAL::ch__batch_test( ch_H_gmp ); CGAL::ch__batch_test( ch_H_gmp );
#endif #endif
CGAL::Homogeneous<double> ch_H_double;
std::cout << "Homogeneous<double>:" << std::endl;
CGAL::ch__batch_test( ch_H_double );
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -25,9 +25,5 @@ int main()
CGAL::ch__batch_test( ch_S_Qgmp ); CGAL::ch__batch_test( ch_S_Qgmp );
#endif #endif
CGAL::Simple_cartesian<double> ch_S_double;
std::cout << "SimpleCartesian<double>:" << std::endl;
CGAL::ch__batch_test( ch_S_double );
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -26,14 +26,9 @@ else()
set(CGAL_ROOT "${CMAKE_SOURCE_DIR}") set(CGAL_ROOT "${CMAKE_SOURCE_DIR}")
endif() endif()
find_package(Doxygen) find_package(Doxygen REQUIRED)
find_package(Python3 REQUIRED COMPONENTS Interpreter) find_package(Python3 REQUIRED COMPONENTS Interpreter)
if(NOT DOXYGEN_FOUND)
message(WARNING "Cannot build the documentation without Doxygen!")
return()
endif()
#starting from cmake 3.9 the usage of DOXYGEN_EXECUTABLE is deprecated #starting from cmake 3.9 the usage of DOXYGEN_EXECUTABLE is deprecated
if(TARGET Doxygen::doxygen) if(TARGET Doxygen::doxygen)
get_property( get_property(
@ -131,6 +126,10 @@ function(configure_doxygen_package CGAL_PACKAGE_NAME)
endif() endif()
endif() endif()
endif() endif()
if(EXISTS "${CGAL_PACKAGE_DIR}/include/CGAL/${CGAL_PACKAGE_NAME}/internal")
file(APPEND ${CGAL_DOC_PACKAGE_DEFAULTS}
"EXCLUDE += ${CGAL_PACKAGE_DIR}/include/CGAL/${CGAL_PACKAGE_NAME}/internal\n")
endif()
# IMAGE_PATH is set by default. For Documentation, we generate the extra path using packages.txt # IMAGE_PATH is set by default. For Documentation, we generate the extra path using packages.txt
set(IMAGE_PATHS "${CGAL_PACKAGE_DOC_DIR}/fig") set(IMAGE_PATHS "${CGAL_PACKAGE_DOC_DIR}/fig")

View File

@ -45,11 +45,11 @@ of `vcpkg` if you want to compile for an older version of a compiler.
Because of a bug with gmp in vcpkg for windows, you need to install `yasm-tool` in 32 bits to be able to correctly build gmp 64bits, needed for cgal: Because of a bug with gmp in vcpkg for windows, you need to install `yasm-tool` in 32 bits to be able to correctly build gmp 64bits, needed for cgal:
C:\dev\vcpkg> ./vcpkg.exe install yasm-tool:x86-windows C:\dev\vcpkg> .\vcpkg.exe install yasm-tool:x86-windows
You are now ready to install \cgal: You are now ready to install \cgal:
C:\dev\vcpkg> ./vcpkg.exe install cgal C:\dev\vcpkg> .\vcpkg.exe install cgal
This will take several minutes as it downloads \gmp, This will take several minutes as it downloads \gmp,
\mpfr, all boost header files, and it will compile \gmp and \mpfr, as well \mpfr, all boost header files, and it will compile \gmp and \mpfr, as well
@ -114,14 +114,14 @@ not depend on `Qt`. However, one of the examples in the Triangulation_2 package
for visualization purposes. If you already have `Qt` installed, you can simply fill in the requested for visualization purposes. If you already have `Qt` installed, you can simply fill in the requested
CMake variables and paths. Otherwise, you can also install it using `vcpkg`: CMake variables and paths. Otherwise, you can also install it using `vcpkg`:
C:\dev\vcpkg> ./vcpkg.exe install qt5 C:\dev\vcpkg> .\vcpkg.exe install qt5
Remember to specify `--triplet` or the related environment variable in case you target 64-bit applications. Remember to specify `--triplet` or the related environment variable in case you target 64-bit applications.
As Qt5 is modular and as the \cgal examples and demos use only some of these modules As Qt5 is modular and as the \cgal examples and demos use only some of these modules
you can save download and compilation time by specifying an *installation option*: you can save download and compilation time by specifying an *installation option*:
C:\dev\vcpkg> ./vcpkg.exe install cgal[qt] C:\dev\vcpkg> .\vcpkg.exe install cgal[qt]
In both cases, when you start `cmake-gui` again and hit the *Configure* button, In both cases, when you start `cmake-gui` again and hit the *Configure* button,
the CMake variables and paths concerning Qt should now be filled. the CMake variables and paths concerning Qt should now be filled.

View File

@ -32,6 +32,17 @@
pages = "39--61" pages = "39--61"
} }
@article{cgal:al-otmnn-08,
title={On the most normal normal},
author={Aubry, Romain and L{\"o}hner, Rainald},
journal={Communications in Numerical Methods in Engineering},
volume={24},
number={12},
pages={1641--1652},
year={2008},
publisher={Wiley Online Library}
}
@manual{ cgal:a-cclga-94 @manual{ cgal:a-cclga-94
,author = {Avnaim, F.} ,author = {Avnaim, F.}
,title = "{C}{\tt ++}{GAL}: {A} {C}{\tt ++} Library for Geometric ,title = "{C}{\tt ++}{GAL}: {A} {C}{\tt ++} Library for Geometric

View File

@ -137313,7 +137313,7 @@ Contains C code."
@inproceedings{ss-kaud-88 @inproceedings{ss-kaud-88
, author = "Th. Strothotte and J.-R. Sack" , author = "Th. Strothotte and J.-R. Sack"
, title = "Knowledge Aquisition using Diagrams" , title = "Knowledge Acquisition using Diagrams"
, booktitle = "Proc. 3rd IFIP Conference on Man-Machine Systems" , booktitle = "Proc. 3rd IFIP Conference on Man-Machine Systems"
, site = "Oulo, Finland" , site = "Oulo, Finland"
, year = 1988 , year = 1988

View File

@ -57,7 +57,7 @@ def write_out_html(d, fn):
f.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n') f.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n')
f.write('<html xmlns=\"https://www.w3.org/1999/xhtml\">') f.write('<html xmlns=\"https://www.w3.org/1999/xhtml\">')
if d.html() is not None: if d.html() is not None:
f.write(d.html()) f.write(d.html(method='html'))
f.write('\n') f.write('\n')
f.write('</html>\n') f.write('</html>\n')
f.close() f.close()

View File

@ -1,3 +1,3 @@
#!/bin/sh #!/bin/sh
exec ${PYTHON_EXECUTABLE} ${CMAKE_BINARY_DIR}/pkglist_filter.py "$1" exec ${Python3_EXECUTABLE} ${CMAKE_BINARY_DIR}/pkglist_filter.py "$1"

View File

@ -1,6 +1,6 @@
@echo off @echo off
:go :go
${PYTHON_EXECUTABLE} ${CMAKE_BINARY_DIR}/pkglist_filter.py %1 ${Python3_EXECUTABLE} ${CMAKE_BINARY_DIR}/pkglist_filter.py %1
@echo on @echo on

View File

@ -98,6 +98,8 @@ public Q_SLOTS:
void on_actionClear_triggered(); void on_actionClear_triggered();
void on_actionOpen_triggered();
void processInput(CGAL::Object); void processInput(CGAL::Object);
void on_actionRecenter_triggered(); void on_actionRecenter_triggered();
@ -105,7 +107,7 @@ public Q_SLOTS:
void on_actionGeneratePointsInSquare_triggered(); void on_actionGeneratePointsInSquare_triggered();
void on_actionGeneratePointsInDisc_triggered(); void on_actionGeneratePointsInDisc_triggered();
void clear(); void clear();
void open(QString fileName);
void update_largest_empty_rectangle(); void update_largest_empty_rectangle();
Q_SIGNALS: Q_SIGNALS:
@ -229,6 +231,50 @@ MainWindow::on_actionClear_triggered()
Q_EMIT( changed()); Q_EMIT( changed());
} }
void
MainWindow::on_actionOpen_triggered()
{
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open points file"),
"."
,tr("xy files (*.xy)")
);
if(! fileName.isEmpty()){
open(fileName);
}
}
void
MainWindow::open(QString fileName)
{
// wait cursor
QApplication::setOverrideCursor(Qt::WaitCursor);
std::ifstream ifs(qPrintable(fileName));
clear();
Point_2 p;
while(ifs >> p){
points.push_back(p);
}
CGAL::Bbox_2 bbox = CGAL::bbox_2(points.begin(), points.end());
square = Iso_rectangle_2(bbox);
ler = Largest_empty_iso_rectangle_2(square);
ler.insert(points.begin(), points.end());
frame[0]->setLine(convert(Segment_2(square.vertex(0),square.vertex(1))));
frame[1]->setLine(convert(Segment_2(square.vertex(1), square.vertex(2))));
frame[2]->setLine(convert(Segment_2(square.vertex(2), square.vertex(3))));
frame[3]->setLine(convert(Segment_2(square.vertex(3), square.vertex(0))));
QApplication::restoreOverrideCursor();
on_actionRecenter_triggered();
Q_EMIT( changed());
}
void void
MainWindow::on_actionRecenter_triggered() MainWindow::on_actionRecenter_triggered()
{ {

View File

@ -80,7 +80,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>500</width> <width>500</width>
<height>26</height> <height>22</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="menuFile"> <widget class="QMenu" name="menuFile">
@ -90,6 +90,7 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionClear"/> <addaction name="actionClear"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionOpen"/>
<addaction name="actionQuit"/> <addaction name="actionQuit"/>
</widget> </widget>
<widget class="QMenu" name="menuTools"> <widget class="QMenu" name="menuTools">
@ -199,6 +200,11 @@
<string>Generate Segment Fans</string> <string>Generate Segment Fans</string>
</property> </property>
</action> </action>
<action name="actionOpen">
<property name="text">
<string>Open</string>
</property>
</action>
</widget> </widget>
<resources> <resources>
<include location="Largest_empty_rectangle_2.qrc"/> <include location="Largest_empty_rectangle_2.qrc"/>

View File

@ -554,87 +554,32 @@ void
MainWindow::loadWKT(QString filename) MainWindow::loadWKT(QString filename)
{ {
std::ifstream ifs(qPrintable(filename)); std::ifstream ifs(qPrintable(filename));
do
{
typedef CGAL::Polygon_with_holes_2<K> Polygon; typedef CGAL::Polygon_with_holes_2<K> Polygon;
typedef CGAL::Point_2<K> Point; typedef CGAL::Point_2<K> Point;
std::vector<Polygon> mps;
CGAL::IO::read_multi_polygon_WKT(ifs, mps); std::deque<Point> points;
for(const Polygon& p : mps) std::deque<std::vector<Point>> linestrings;
{ std::deque<Polygon> polygons;
CGAL::IO::read_WKT(ifs, points, linestrings, polygons);
cdt.insert(points.begin(),points.end());
for(const std::vector<Point>& line : linestrings){
cdt.insert_constraint(line.begin(), line.end());
}
for(const Polygon& p : polygons){
if(p.outer_boundary().is_empty()) if(p.outer_boundary().is_empty())
continue; continue;
for(Point point : p.outer_boundary().container()) cdt.insert_constraint(p.outer_boundary().vertices_begin(), p.outer_boundary().vertices_end(),true);
cdt.insert(point);
for(Polygon::General_polygon_2::Edge_const_iterator
e_it=p.outer_boundary().edges_begin(); e_it != p.outer_boundary().edges_end(); ++e_it)
cdt.insert_constraint(e_it->source(), e_it->target());
for(Polygon::Hole_const_iterator h_it = for(Polygon::Hole_const_iterator h_it = p.holes_begin(); h_it != p.holes_end(); ++h_it){
p.holes_begin(); h_it != p.holes_end(); ++h_it) cdt.insert_constraint(h_it->vertices_begin(), h_it->vertices_end(),true);
{
for(Point point : h_it->container())
cdt.insert(point);
for(Polygon::General_polygon_2::Edge_const_iterator
e_it=h_it->edges_begin(); e_it != h_it->edges_end(); ++e_it)
{
cdt.insert_constraint(e_it->source(), e_it->target());
} }
} }
}
}while(ifs.good() && !ifs.eof());
//Edges
ifs.clear();
ifs.seekg(0, ifs.beg);
do
{
typedef std::vector<K::Point_2> LineString;
std::vector<LineString> mls;
CGAL::IO::read_multi_linestring_WKT(ifs, mls);
for(const LineString& ls : mls)
{
if(ls.empty())
continue;
K::Point_2 p,q, qold(0,0); // initialize to avoid maybe-uninitialized warning from GCC6
bool first = true;
CDT::Vertex_handle vp, vq, vqold;
LineString::const_iterator it =
ls.begin();
for(; it != ls.end(); ++it) {
p = *it++;
q = *it;
if(p == q){
continue;
}
if((!first) && (p == qold)){
vp = vqold;
} else {
vp = cdt.insert(p);
}
vq = cdt.insert(q, vp->face());
if(vp != vq) {
cdt.insert_constraint(vp,vq);
}
qold = q;
vqold = vq;
first = false;
}
}
}while(ifs.good() && !ifs.eof());
//Points
ifs.clear();
ifs.seekg(0, ifs.beg);
do
{
std::vector<K::Point_2> mpts;
CGAL::IO::read_multi_point_WKT(ifs, mpts);
for(const K::Point_2& p : mpts)
{
cdt.insert(p);
}
}while(ifs.good() && !ifs.eof());
discoverComponents(cdt, m_seeds); discoverComponents(cdt, m_seeds);
Q_EMIT( changed()); Q_EMIT( changed());

View File

@ -142,9 +142,11 @@ Iso_rectangle_2 get_bounding_box();
/// @{ /// @{
/*! /*!
Inserts point `p` in the point set, if it is not already in the set. Inserts point `p` in the point set, if it is not already in the set
and on the bounded side of the bounding rectangle.
\note Points on the boundary can be ignored as they lead to the same result.
*/ */
void bool
insert(const Point_2& p); insert(const Point_2& p);
/*! /*!

View File

@ -1,8 +1,7 @@
#include <CGAL/Simple_cartesian.h> #include <CGAL/Simple_cartesian.h>
#include <CGAL/Iso_rectangle_2.h>
#include <CGAL/Largest_empty_iso_rectangle_2.h> #include <CGAL/Largest_empty_iso_rectangle_2.h>
#include <fstream> #include <iostream>
typedef double Number_Type; typedef double Number_Type;
typedef CGAL::Simple_cartesian<Number_Type> K; typedef CGAL::Simple_cartesian<Number_Type> K;

View File

@ -762,7 +762,7 @@ bool
Largest_empty_iso_rectangle_2<T>::insert(const Point_2& _p) Largest_empty_iso_rectangle_2<T>::insert(const Point_2& _p)
{ {
// check that the point is inside the bounding box // check that the point is inside the bounding box
if(bbox_p.has_on_unbounded_side(_p)) { if(! bbox_p.has_on_bounded_side(_p)) {
return(false); return(false);
} }

View File

@ -20,8 +20,8 @@ Release date: June 2023
`CGAL::Polygon_mesh_processing::triangulate_and_refine_hole()`, and `CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole()` `CGAL::Polygon_mesh_processing::triangulate_and_refine_hole()`, and `CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole()`
which have output iterators for vertices and faces as parameter. They are replaced by overloads with two additional named parameters. which have output iterators for vertices and faces as parameter. They are replaced by overloads with two additional named parameters.
- Added the function `CGAL::Polygon_mesh_processing::surface_Delaunay_remeshing()`, that remeshes a surface triangle mesh following the - Added the function `CGAL::Polygon_mesh_processing::surface_Delaunay_remeshing()`, that remeshes a surface triangle mesh using
CGAL tetrahedral Delaunay refinement algorithm. the Delaunay refinement algorithm from the 3D Mesh Generation package.
- Added the function `CGAL::Polygon_mesh_processing::remove_almost_degenerate_faces()` to remove badly shaped triangles faces in a mesh. - Added the function `CGAL::Polygon_mesh_processing::remove_almost_degenerate_faces()` to remove badly shaped triangles faces in a mesh.
@ -67,6 +67,9 @@ CGAL tetrahedral Delaunay refinement algorithm.
- The stop predicates `Count_stop_predicate` and `Count_ratio_stop_predicate` are renamed to `Edge_count_stop_predicate` and `Edge_count_ratio_stop_predicate`. Older versions have been deprecated. - The stop predicates `Count_stop_predicate` and `Count_ratio_stop_predicate` are renamed to `Edge_count_stop_predicate` and `Edge_count_ratio_stop_predicate`. Older versions have been deprecated.
- Introduce `Face_count_stop_predicate` and `Face_count_ratio_stop_predicate` that can be used to stop the simplification algorithm based on a desired number of faces in the output, or a ratio between input and output face numbers. - Introduce `Face_count_stop_predicate` and `Face_count_ratio_stop_predicate` that can be used to stop the simplification algorithm based on a desired number of faces in the output, or a ratio between input and output face numbers.
### [2D Minkowski Sums](https://doc.cgal.org/5.6/Manual/packages.html#PkgMinkowskiSum2)
- Fixed a bug that made holes in the Minkowski sum disappear
[Release 5.5](https://github.com/CGAL/cgal/releases/tag/v5.5) [Release 5.5](https://github.com/CGAL/cgal/releases/tag/v5.5)
----------- -----------

View File

@ -41,11 +41,7 @@ if ( NOT CGAL_GENERATOR_SPECIFIC_SETTINGS_FILE_INCLUDED )
IF (APPLE) IF (APPLE)
exec_program(uname ARGS -v OUTPUT_VARIABLE DARWIN_VERSION) exec_program(uname ARGS -v OUTPUT_VARIABLE DARWIN_VERSION)
string(REGEX MATCH "[0-9]+" DARWIN_VERSION ${DARWIN_VERSION}) string(REGEX MATCH "[0-9]+" DARWIN_VERSION ${DARWIN_VERSION})
message(STATUS "DARWIN_VERSION=${DARWIN_VERSION}") message(STATUS "Running in macOS DARWIN_VERSION=${DARWIN_VERSION}")
if (DARWIN_VERSION GREATER 8)
message(STATUS "Mac Leopard detected")
set(CGAL_APPLE_LEOPARD 1)
endif()
endif() endif()
if ( NOT "${CMAKE_CFG_INTDIR}" STREQUAL "." ) if ( NOT "${CMAKE_CFG_INTDIR}" STREQUAL "." )

View File

@ -435,6 +435,22 @@ Segment_2_Segment_2_pair<K>::intersection_type() const
: CGAL::make_array( _seg2->point(s2s2_id[c][2]), _seg2->point(s2s2_id[c][3]), : CGAL::make_array( _seg2->point(s2s2_id[c][2]), _seg2->point(s2s2_id[c][3]),
_seg1->point(s2s2_id[c][0]), _seg1->point(s2s2_id[c][1]) ); _seg1->point(s2s2_id[c][0]), _seg1->point(s2s2_id[c][1]) );
// special case for vertical and horizontal segments
if (std::is_floating_point<typename K::FT>::value &&
std::is_same<typename K::Kernel_tag, Cartesian_tag>::value)
{
if (pts[0].x()==pts[1].x() && pts[2].y()==pts[3].y())
{
_intersection_point = K().construct_point_2_object()(pts[0].x(), pts[2].y());
return _result;
}
if (pts[0].y()==pts[1].y() && pts[2].x()==pts[3].x())
{
_intersection_point = K().construct_point_2_object()(pts[2].x(), pts[0].y());
return _result;
}
}
typename K::FT alpha = s2s2_alpha(pts[0].x(), pts[0].y(), pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y(), pts[3].x(), pts[3].y()); typename K::FT alpha = s2s2_alpha(pts[0].x(), pts[0].y(), pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y(), pts[3].x(), pts[3].y());
_intersection_point = K().construct_barycenter_2_object()(pts[0], alpha, pts[1]); _intersection_point = K().construct_barycenter_2_object()(pts[0], alpha, pts[1]);

View File

@ -18,6 +18,7 @@
#include <CGAL/enum.h> #include <CGAL/enum.h>
#include <CGAL/kernel_assertions.h> #include <CGAL/kernel_assertions.h>
#include <iterator>
namespace CGAL { namespace CGAL {
namespace Intersections { namespace Intersections {
@ -141,7 +142,7 @@ intersection(const typename K::Plane_3& plane,
CGAL_kernel_assertion(pts.size() == 2); CGAL_kernel_assertion(pts.size() == 2);
return intersection_return<typename K::Intersect_3, typename K::Plane_3, typename K::Triangle_3>( return intersection_return<typename K::Intersect_3, typename K::Plane_3, typename K::Triangle_3>(
k.construct_segment_3_object()(*pts.begin(), *boost::prior(pts.end()))); k.construct_segment_3_object()(*pts.begin(), *std::prev(pts.end())));
} }
template <class K> template <class K>

View File

@ -51,7 +51,7 @@ void intersection_coplanar_triangles_cutoff(const typename Kernel::Point_3& p,
for (Iterator it=inter_pts.begin();it!=inter_pts.end();++it) for (Iterator it=inter_pts.begin();it!=inter_pts.end();++it)
orientations[ &(*it) ]=orient(p,q,r,*it); orientations[ &(*it) ]=orient(p,q,r,*it);
int pt_added = 0; CGAL_kernel_assertion_code(int pt_added = 0;)
const typename Kernel::Point_3* prev = &(*boost::prior(inter_pts.end())); const typename Kernel::Point_3* prev = &(*boost::prior(inter_pts.end()));
Iterator stop = inter_pts.size() > 2 ? inter_pts.end() : boost::prior(inter_pts.end()); Iterator stop = inter_pts.size() > 2 ? inter_pts.end() : boost::prior(inter_pts.end());
@ -75,7 +75,7 @@ void intersection_coplanar_triangles_cutoff(const typename Kernel::Point_3& p,
prev = &(*inter_pts.insert(it,*inter)); prev = &(*inter_pts.insert(it,*inter));
orientations[prev] = COLLINEAR; orientations[prev] = COLLINEAR;
++pt_added; CGAL_kernel_assertion_code(++pt_added;)
} }
prev = &(*it); prev = &(*it);

View File

@ -238,7 +238,7 @@ public:
const auto ires12 = CGAL::intersection(o1, o2); const auto ires12 = CGAL::intersection(o1, o2);
Res tmp; Res tmp;
if(has_exact_p) if(has_exact_c)
{ {
assert(CGAL::assign(tmp, ires12)); assert(CGAL::assign(tmp, ires12));
assert(approx_equal(tmp, result)); assert(approx_equal(tmp, result));
@ -246,7 +246,7 @@ public:
else else
{ {
if(CGAL::assign(tmp, ires12)) if(CGAL::assign(tmp, ires12))
assert(approx_equal(tmp, result)); CGAL_warning(approx_equal(tmp, result));
else else
CGAL_warning_msg(false, "Expected an intersection, but it was not found!"); CGAL_warning_msg(false, "Expected an intersection, but it was not found!");
} }

View File

@ -25,7 +25,7 @@ protected:
//i >= 1; from a start vertex on the current i-1 ring, push non-visited neighbors //i >= 1; from a start vertex on the current i-1 ring, push non-visited neighbors
//of start in the nextRing and set indices to i. Also add these vertices in all. //of start in the nextRing and set indices to i. Also add these vertices in all.
static void push_neighbours_of(Vertex * start, int ith, static void push_neighbors_of(Vertex * start, int ith,
std::vector < Vertex * >&nextRing, std::vector < Vertex * >&nextRing,
std::vector < Vertex * >&all, std::vector < Vertex * >&all,
VertexPropertyMap& vpm); VertexPropertyMap& vpm);
@ -58,7 +58,7 @@ protected:
template < class TPoly , class VertexPropertyMap> template < class TPoly , class VertexPropertyMap>
void T_PolyhedralSurf_rings <TPoly, VertexPropertyMap>:: void T_PolyhedralSurf_rings <TPoly, VertexPropertyMap>::
push_neighbours_of(Vertex * start, int ith, push_neighbors_of(Vertex * start, int ith,
std::vector < Vertex * >&nextRing, std::vector < Vertex * >&nextRing,
std::vector < Vertex * >&all, std::vector < Vertex * >&all,
VertexPropertyMap& vpm) VertexPropertyMap& vpm)
@ -88,7 +88,7 @@ collect_ith_ring(int ith, std::vector < Vertex * >&currentRing,
typename std::vector < Vertex * >::iterator typename std::vector < Vertex * >::iterator
itb = currentRing.begin(), ite = currentRing.end(); itb = currentRing.begin(), ite = currentRing.end();
CGAL_For_all(itb, ite) push_neighbours_of(*itb, ith, nextRing, all, vpm); CGAL_For_all(itb, ite) push_neighbors_of(*itb, ith, nextRing, all, vpm);
} }
template <class TPoly, class VertexPropertyMap> template <class TPoly, class VertexPropertyMap>

View File

@ -107,7 +107,7 @@ approximates the rotation over the angle indicated by direction
`d`, such that the differences between the sines and cosines `d`, such that the differences between the sines and cosines
of the rotation given by d and the approximating rotation of the rotation given by d and the approximating rotation
are at most \f$ num/den\f$ each. are at most \f$ num/den\f$ each.
\pre \f$ num/den>0\f$ and \f$ d != 0\f$. \pre `num/den > 0` and `d != 0`.
*/ */
Aff_transformation_2(const Rotation, Aff_transformation_2(const Rotation,
const Direction_2<Kernel> &d, const Direction_2<Kernel> &d,
@ -116,7 +116,7 @@ const Kernel::RT &den = RT(1));
/*! /*!
introduces a rotation by the angle `rho`. introduces a rotation by the angle `rho`.
\pre \f$ sine\_rho^2 + cosine\_rho^2 == hw^2\f$. \pre <tt>sine\_rho<sup>2</sup> + cosine\_rho<sup>2</sup> == hw<sup>2</sup></tt>.
*/ */
Aff_transformation_2(const Rotation, Aff_transformation_2(const Rotation,
const Kernel::RT &sine_rho, const Kernel::RT &sine_rho,

View File

@ -77,13 +77,13 @@ double ymax() const;
/*! /*!
Returns `xmin()` if `i==0` or `ymin()` if `i==1`. Returns `xmin()` if `i==0` or `ymin()` if `i==1`.
\pre i==0 or i==1 \pre `i==0` or `i==1`
*/ */
double min(int i) const; double min(int i) const;
/*! /*!
Returns `xmax()` if `i==0` or `ymax()` if `i==1`. Returns `xmax()` if `i==0` or `ymax()` if `i==1`.
\pre i==0 or i==1 \pre `i==0` or `i==1`
*/ */
double max(int i) const; double max(int i) const;

View File

@ -90,14 +90,14 @@ double zmax() const;
/*! /*!
Returns `xmin()` if `i==0` or `ymin()` if `i==1` Returns `xmin()` if `i==0` or `ymin()` if `i==1`
or `zmin()` if `i==2`. or `zmin()` if `i==2`.
\pre i>=0 and i<=2 \pre `i>=0` and `i<=2`
*/ */
double min(int i) const; double min(int i) const;
/*! /*!
Returns `xmax()` if `i==0` or `ymax()` if `i==1` Returns `xmax()` if `i==0` or `ymax()` if `i==1`
or `zmax()` if `i==2`. or `zmax()` if `i==2`.
\pre i>=0 and i<=2 \pre `i>=0` and `i<=2`
*/ */
double max(int i) const; double max(int i) const;

View File

@ -28,7 +28,7 @@ introduces a variable `c` of type `Circle_2`.
It is initialized to the circle with center `center`, It is initialized to the circle with center `center`,
squared radius `squared_radius` and orientation squared radius `squared_radius` and orientation
`ori`. `ori`.
\pre `ori` \f$ \neq\f$ `COLLINEAR`, and further, `squared_radius` \f$ \geq\f$ 0. \pre `ori != COLLINEAR` and `squared_radius >= 0`.
*/ */
Circle_2(const Point_2<Kernel> &center, Circle_2(const Point_2<Kernel> &center,
const Kernel::FT &squared_radius, const Kernel::FT &squared_radius,
@ -52,7 +52,7 @@ const Point_2<Kernel> &r);
introduces a variable `c` of type `Circle_2`. introduces a variable `c` of type `Circle_2`.
It is initialized to the circle with diameter \f$ \overline{pq}\f$ It is initialized to the circle with diameter \f$ \overline{pq}\f$
and orientation `ori`. and orientation `ori`.
\pre `ori` \f$ \neq\f$ `COLLINEAR`. \pre `ori != COLLINEAR`.
*/ */
Circle_2( const Point_2<Kernel> &p, Circle_2( const Point_2<Kernel> &p,
const Point_2<Kernel> &q, const Point_2<Kernel> &q,
@ -63,7 +63,7 @@ const Orientation &ori = COUNTERCLOCKWISE);
introduces a variable `c` of type `Circle_2`. introduces a variable `c` of type `Circle_2`.
It is initialized to the circle with center `center`, squared It is initialized to the circle with center `center`, squared
radius zero and orientation `ori`. radius zero and orientation `ori`.
\pre `ori` \f$ \neq\f$ `COLLINEAR`. \pre `ori != COLLINEAR`.
\post `c.is_degenerate()` = `true`. \post `c.is_degenerate()` = `true`.
*/ */
Circle_2( const Point_2<Kernel> &center, Circle_2( const Point_2<Kernel> &center,

View File

@ -21,7 +21,7 @@ public:
introduces a variable `c` of type `Circle_3`. introduces a variable `c` of type `Circle_3`.
It is initialized to the circle of center `center` and It is initialized to the circle of center `center` and
squared radius `sq_r` in plane `plane`. squared radius `sq_r` in plane `plane`.
\pre `center` lies in `plane` and `sq_r` \f$ \geq\f$ 0. \pre `center` lies in `plane` and `sq_r >= 0`.
*/ */
Circle_3(const Point_3<Kernel> &center, Circle_3(const Point_3<Kernel> &center,
const Kernel::FT &sq_r, const Kernel::FT &sq_r,
@ -32,7 +32,7 @@ introduces a variable `c` of type `Circle_3`.
It is initialized to the circle of center `center` and It is initialized to the circle of center `center` and
squared radius `sq_r` in a plane normal to squared radius `sq_r` in a plane normal to
the vector `n`. the vector `n`.
\pre `sq_r` \f$ \geq\f$ 0. \pre `sq_r >= 0`.
*/ */
Circle_3(const Point_3<Kernel> & center, Circle_3(const Point_3<Kernel> & center,
const Kernel::FT & sq_r, const Kernel::FT & sq_r,

View File

@ -60,7 +60,7 @@ Direction_2(const Kernel::RT &x, const Kernel::RT &y);
/*! /*!
returns values, such that `d``== Direction_2<Kernel>(delta(0),delta(1))`. returns values, such that `d``== Direction_2<Kernel>(delta(0),delta(1))`.
\pre \f$ 0 \leq i \leq1\f$. \pre `0 <= i <= 1`.
*/ */
Kernel::RT delta(int i) const; Kernel::RT delta(int i) const;

View File

@ -57,7 +57,7 @@ Direction_3(const Kernel::RT &x, const Kernel::RT &y, const Kernel::RT &z);
/*! /*!
returns values, such that `d``== Direction_3<Kernel>(delta(0),delta(1),delta(2))`. returns values, such that `d``== Direction_3<Kernel>(delta(0),delta(1),delta(2))`.
\pre \f$ 0 \leq i \leq2\f$. \pre `0 <= i <= 2`.
*/ */
Kernel::RT delta(int i) const; Kernel::RT delta(int i) const;

View File

@ -65,7 +65,7 @@ introduces an iso-oriented cuboid `c` with diagonal
opposite vertices opposite vertices
(`min_hx/hw`, `min_hy/hw`, `min_hz/hw`) and (`min_hx/hw`, `min_hy/hw`, `min_hz/hw`) and
(`max_hx/hw`, `max_hy/hw`, `max_hz/hw`). (`max_hx/hw`, `max_hy/hw`, `max_hz/hw`).
\pre `hw` \f$ \neq\f$ 0. \pre `hw != 0`.
*/ */
Iso_cuboid_3( Iso_cuboid_3(
const Kernel::RT& min_hx, const Kernel::RT& min_hy, const Kernel::RT& min_hz, const Kernel::RT& min_hx, const Kernel::RT& min_hy, const Kernel::RT& min_hz,
@ -156,14 +156,14 @@ Kernel::FT zmax() const;
/*! /*!
returns `i`-th %Cartesian coordinate of returns `i`-th %Cartesian coordinate of
the smallest vertex of `c`. the smallest vertex of `c`.
\pre \f$ 0 \leq i \leq2\f$. \pre `0 <= i <= 2`.
*/ */
Kernel::FT min_coord(int i) const; Kernel::FT min_coord(int i) const;
/*! /*!
returns `i`-th %Cartesian coordinate of returns `i`-th %Cartesian coordinate of
the largest vertex of `c`. the largest vertex of `c`.
\pre \f$ 0 \leq i \leq2\f$. \pre `0 <= i <= 2`.
*/ */
Kernel::FT max_coord(int i) const; Kernel::FT max_coord(int i) const;

View File

@ -62,7 +62,7 @@ const Point_2<Kernel> &top);
introduces an iso-oriented rectangle `r` with diagonal introduces an iso-oriented rectangle `r` with diagonal
opposite vertices (`min_hx/hw`, `min_hy/hw`) and opposite vertices (`min_hx/hw`, `min_hy/hw`) and
(`max_hx/hw`, `max_hy/hw`). (`max_hx/hw`, `max_hy/hw`).
\pre `hw` \f$ \neq\f$ 0. \pre `hw != 0`.
*/ */
Iso_rectangle_2(const Kernel::RT& min_hx, const Kernel::RT& min_hy, Iso_rectangle_2(const Kernel::RT& min_hx, const Kernel::RT& min_hy,
const Kernel::RT& max_hx, const Kernel::RT& max_hy, const Kernel::RT& max_hx, const Kernel::RT& max_hy,
@ -134,14 +134,14 @@ Kernel::FT ymax() const;
/*! /*!
returns the `i`'th %Cartesian coordinate of the returns the `i`'th %Cartesian coordinate of the
lower left vertex of `r`. lower left vertex of `r`.
\pre \f$ 0 \leq i \leq1\f$. \pre `0 <= i <= 1`.
*/ */
Kernel::FT min_coord(int i) const; Kernel::FT min_coord(int i) const;
/*! /*!
returns the `i`'th %Cartesian coordinate of the returns the `i`'th %Cartesian coordinate of the
upper right vertex of `r`. upper right vertex of `r`.
\pre \f$ 0 \leq i \leq1\f$. \pre `0 <= i <= 1`.
*/ */
Kernel::FT max_coord(int i) const; Kernel::FT max_coord(int i) const;

View File

@ -89,7 +89,7 @@ Angle angle(const CGAL::Point_3<Kernel>&p,
/*! /*!
returns an approximation of the angle between `p-q` and `r-q`. returns an approximation of the angle between `p-q` and `r-q`.
The angle is given in degrees. The angle is given in degrees.
\pre `p` and `r` are not equal to `q`. \pre `p != q` and `r != q`.
*/ */
template <typename Kernel> template <typename Kernel>
Kernel::FT approximate_angle(const CGAL::Point_3<Kernel>& p, Kernel::FT approximate_angle(const CGAL::Point_3<Kernel>& p,
@ -341,7 +341,7 @@ const CGAL::Point_3<Kernel>& p4, const Kernel::FT&w4);
/*! /*!
constructs the bisector line of the two points `p` and `q`. constructs the bisector line of the two points `p` and `q`.
The bisector is oriented in such a way that `p` lies on its The bisector is oriented in such a way that `p` lies on its
positive side. \pre `p` and `q` are not equal. positive side. \pre `p != q`.
*/ */
template <typename Kernel> template <typename Kernel>
CGAL::Line_2<Kernel> bisector(const CGAL::Point_2<Kernel> &p, CGAL::Line_2<Kernel> bisector(const CGAL::Point_2<Kernel> &p,
@ -367,7 +367,7 @@ const CGAL::Line_2<Kernel> &l2);
/*! /*!
constructs the bisector plane of the two points `p` and `q`. constructs the bisector plane of the two points `p` and `q`.
The bisector is oriented in such a way that `p` lies on its The bisector is oriented in such a way that `p` lies on its
positive side. \pre `p` and `q` are not equal. positive side. \pre `p != q'.
*/ */
template <typename Kernel> template <typename Kernel>
CGAL::Plane_3<Kernel> bisector(const CGAL::Point_3<Kernel> &p, CGAL::Plane_3<Kernel> bisector(const CGAL::Point_3<Kernel> &p,

View File

@ -71,7 +71,7 @@ Point_2(double x, double y);
/*! /*!
introduces a point `p` initialized to `(hx/hw,hy/hw)`. introduces a point `p` initialized to `(hx/hw,hy/hw)`.
\pre `hw` \f$ \neq\f$ `Kernel::RT(0)`. \pre `hw != Kernel::RT(0)`.
*/ */
Point_2(const Kernel::RT &hx, const Kernel::RT &hy, const Kernel::RT &hw = RT(1)); Point_2(const Kernel::RT &hx, const Kernel::RT &hy, const Kernel::RT &hw = RT(1));
@ -159,19 +159,19 @@ Kernel::FT y() const;
/*! /*!
returns the i'th homogeneous coordinate of `p`. returns the i'th homogeneous coordinate of `p`.
\pre \f$ 0\leq i \leq2\f$. \pre `0 <= i <= 2`.
*/ */
Kernel::RT homogeneous(int i) const; Kernel::RT homogeneous(int i) const;
/*! /*!
returns the i'th %Cartesian coordinate of `p`. returns the i'th %Cartesian coordinate of `p`.
\pre \f$ 0\leq i \leq1\f$. \pre `0 <= i <= 1`.
*/ */
Kernel::FT cartesian(int i) const; Kernel::FT cartesian(int i) const;
/*! /*!
returns `cartesian(i)`. returns `cartesian(i)`.
\pre \f$ 0\leq i \leq1\f$. \pre `0 <= i <= 1`.
*/ */
Kernel::FT operator[](int i) const; Kernel::FT operator[](int i) const;

View File

@ -56,7 +56,7 @@ Point_3(double x, double y, double z);
/*! /*!
introduces a point `p` initialized to `(hx/hw,hy/hw, hz/hw)`. introduces a point `p` initialized to `(hx/hw,hy/hw, hz/hw)`.
\pre `hw` \f$ \neq\f$ 0. \pre `hw != 0`.
*/ */
Point_3(const Kernel::RT &hx, const Kernel::RT &hy, const Kernel::RT &hz, const Kernel::RT &hw = RT(1)); Point_3(const Kernel::RT &hx, const Kernel::RT &hy, const Kernel::RT &hz, const Kernel::RT &hw = RT(1));
@ -154,19 +154,19 @@ Kernel::FT z() const;
/*! /*!
returns the i'th homogeneous coordinate of `p`. returns the i'th homogeneous coordinate of `p`.
\pre \f$ 0\leq i \leq3\f$. \pre `0 <= i <= 3`.
*/ */
Kernel::RT homogeneous(int i) const; Kernel::RT homogeneous(int i) const;
/*! /*!
returns the i'th %Cartesian coordinate of `p`. returns the i'th %Cartesian coordinate of `p`.
\pre \f$ 0\leq i \leq2\f$. \pre `0 <= i <= 2`.
*/ */
Kernel::FT cartesian(int i) const; Kernel::FT cartesian(int i) const;
/*! /*!
returns `cartesian(i)`. returns `cartesian(i)`.
\pre \f$ 0\leq i \leq2\f$. \pre `0 <= i <= 2`.
*/ */
Kernel::FT operator[](int i) const; Kernel::FT operator[](int i) const;

View File

@ -65,7 +65,7 @@ Point_2<Kernel> source() const;
/*! /*!
returns a point on `r`. `point(0)` is the source, returns a point on `r`. `point(0)` is the source,
`point(i)`, with `i>0`, is different from the `point(i)`, with `i>0`, is different from the
source. \pre \f$ i \geq0\f$. source. \pre `i >= 0`.
*/ */
Point_2<Kernel> point(const Kernel::FT i) const; Point_2<Kernel> point(const Kernel::FT i) const;

View File

@ -65,7 +65,7 @@ Point_3<Kernel> source() const;
/*! /*!
returns a point on `r`. `point(0)` is the source. returns a point on `r`. `point(0)` is the source.
`point(i)`, with `i>0`, is different from the `point(i)`, with `i>0`, is different from the
source. \pre \f$ i \geq0\f$. source. \pre `i >= 0`.
*/ */
Point_3<Kernel> point(const Kernel::FT i) const; Point_3<Kernel> point(const Kernel::FT i) const;

View File

@ -28,7 +28,7 @@ introduces a variable `c` of type `Sphere_3`.
It is initialized to the sphere with center `center`, It is initialized to the sphere with center `center`,
squared radius `squared_radius` and orientation squared radius `squared_radius` and orientation
`orientation`. `orientation`.
\pre `orientation` \f$ \neq\f$ \ref COPLANAR, and furthermore, `squared_radius` \f$ \geq\f$ 0. \pre `orientation != COPLANAR` and `squared_radius >= 0`.
*/ */
Sphere_3( const Point_3<Kernel> & center, Sphere_3( const Point_3<Kernel> & center,
const Kernel::FT & squared_radius, const Kernel::FT & squared_radius,
@ -53,7 +53,7 @@ const Point_3<Kernel> & s);
introduces a variable `c` of type `Sphere_3`. introduces a variable `c` of type `Sphere_3`.
It is initialized to the smallest sphere which passes through It is initialized to the smallest sphere which passes through
the points `p`, `q`, and `r`. The orientation of the points `p`, `q`, and `r`. The orientation of
the sphere is `o`. \pre `o` is not \ref COPLANAR. the sphere is `o`. \pre `o != COPLANAR`.
*/ */
Sphere_3( const Point_3<Kernel> & p, Sphere_3( const Point_3<Kernel> & p,
const Point_3<Kernel> & q, const Point_3<Kernel> & q,
@ -65,7 +65,7 @@ const Orientation& o = COUNTERCLOCKWISE);
introduces a variable `c` of type `Sphere_3`. introduces a variable `c` of type `Sphere_3`.
It is initialized to the smallest sphere which passes through It is initialized to the smallest sphere which passes through
the points `p` and `q`. The orientation of the points `p` and `q`. The orientation of
the sphere is `o`. \pre `o` is not \ref COPLANAR. the sphere is `o`. \pre `o != COPLANAR`.
*/ */
Sphere_3( const Point_3<Kernel> & p, Sphere_3( const Point_3<Kernel> & p,
const Point_3<Kernel> & q, const Point_3<Kernel> & q,
@ -76,7 +76,7 @@ const Orientation& o = COUNTERCLOCKWISE);
introduces a variable `c` of type `Sphere_3`. introduces a variable `c` of type `Sphere_3`.
It is initialized to the sphere with center `center`, squared It is initialized to the sphere with center `center`, squared
radius zero and orientation `orientation`. radius zero and orientation `orientation`.
\pre `orientation` \f$ \neq\f$ \ref COPLANAR. \pre `orientation != COPLANAR`.
\post `c.is_degenerate()` = `true`. \post `c.is_degenerate()` = `true`.
*/ */
Sphere_3( const Point_3<Kernel> & center, Sphere_3( const Point_3<Kernel> & center,

View File

@ -71,7 +71,7 @@ Vector_2(double x, double y);
/*! /*!
introduces a vector `v` initialized to `(hx/hw,hy/hw)`. introduces a vector `v` initialized to `(hx/hw,hy/hw)`.
\pre \f$ hw\neq0\f$. \pre `hw != 0`.
*/ */
Vector_2(const Kernel::RT &hx, const Kernel::RT &hy, const Kernel::RT &hw = RT(1)); Vector_2(const Kernel::RT &hx, const Kernel::RT &hy, const Kernel::RT &hw = RT(1));
@ -126,19 +126,19 @@ Kernel::FT y() const;
/*! /*!
returns the i'th homogeneous coordinate of `v`. returns the i'th homogeneous coordinate of `v`.
\pre \f$ 0\leq i \leq2\f$. \pre `0 <= i <= 2`.
*/ */
Kernel::RT homogeneous(int i) const; Kernel::RT homogeneous(int i) const;
/*! /*!
returns the i'th Cartesian coordinate of `v`. returns the i'th Cartesian coordinate of `v`.
\pre \f$ 0\leq i \leq1\f$. \pre `0 <= i <= 1`.
*/ */
Kernel::FT cartesian(int i) const; Kernel::FT cartesian(int i) const;
/*! /*!
returns `cartesian(i)`. returns `cartesian(i)`.
\pre \f$ 0\leq i \leq1\f$. \pre `0 <= i <= 1`.
*/ */
Kernel::FT operator[](int i) const; Kernel::FT operator[](int i) const;

View File

@ -137,19 +137,19 @@ Kernel::FT z() const;
/*! /*!
returns the i'th homogeneous coordinate of `v`. returns the i'th homogeneous coordinate of `v`.
\pre \f$ 0\leq i \leq3\f$. \pre `0 <= i <= 3`.
*/ */
Kernel::RT homogeneous(int i) const; Kernel::RT homogeneous(int i) const;
/*! /*!
returns the i'th %Cartesian coordinate of `v`. returns the i'th %Cartesian coordinate of `v`.
\pre \f$ 0\leq i \leq2\f$. \pre `0 <= i <= 2`
*/ */
Kernel::FT cartesian(int i) const; Kernel::FT cartesian(int i) const;
/*! /*!
returns `cartesian(i)`. returns `cartesian(i)`.
\pre \f$ 0\leq i \leq2\f$. \pre `0 <= i <= 2`
*/ */
Kernel::FT operator[](int i) const; Kernel::FT operator[](int i) const;

View File

@ -147,19 +147,19 @@ public:
/*! /*!
returns the i'th homogeneous coordinate of `p`. returns the i'th homogeneous coordinate of `p`.
\pre \f$ 0\leq i \leq2\f$. \pre `0 <= i <= 2`
*/ */
Kernel::RT homogeneous(int i) const; Kernel::RT homogeneous(int i) const;
/*! /*!
returns the i'th %Cartesian coordinate of `p`. returns the i'th %Cartesian coordinate of `p`.
\pre \f$ 0\leq i \leq1\f$. \pre `0 <= i <= 1`
*/ */
Kernel::FT cartesian(int i) const; Kernel::FT cartesian(int i) const;
/*! /*!
returns `cartesian(i)`. returns `cartesian(i)`.
\pre \f$ 0\leq i \leq1\f$. \pre `0 <= i <= 1`
*/ */
Kernel::FT operator[](int i) const; Kernel::FT operator[](int i) const;

View File

@ -157,19 +157,19 @@ public:
/*! /*!
returns the i'th homogeneous coordinate of `p`. returns the i'th homogeneous coordinate of `p`.
\pre \f$ 0\leq i \leq3\f$. \pre `0 <= i <= 3`
*/ */
Kernel::RT homogeneous(int i) const; Kernel::RT homogeneous(int i) const;
/*! /*!
returns the i'th %Cartesian coordinate of `p`. returns the i'th %Cartesian coordinate of `p`.
\pre \f$ 0\leq i \leq2\f$. \pre `0 <= i <= 2`
*/ */
Kernel::FT cartesian(int i) const; Kernel::FT cartesian(int i) const;
/*! /*!
returns `cartesian(i)`. returns `cartesian(i)`.
\pre \f$ 0\leq i \leq2\f$. \pre `0 <= i <= 2`
*/ */
Kernel::FT operator[](int i) const; Kernel::FT operator[](int i) const;

View File

@ -7,7 +7,7 @@ computes integers `sin_num`, `cos_num` and `denom`, such
that `sin_num`/`denom` approximates the sine of direction that `sin_num`/`denom` approximates the sine of direction
\f$ (\f$`dirx`,`diry`\f$ )\f$. The difference between the sine and \f$ (\f$`dirx`,`diry`\f$ )\f$. The difference between the sine and
the approximating rational is bounded by `eps_num`/`eps_den`. the approximating rational is bounded by `eps_num`/`eps_den`.
\pre `eps_num` \f$ \neq0\f$. \pre `eps_num != 0`.
\cgalHeading{Implementation} \cgalHeading{Implementation}

View File

@ -3879,7 +3879,7 @@ public:
/*! /*!
constructs the bisector of `p` and `q`. constructs the bisector of `p` and `q`.
The bisector is oriented in such a way that `p` lies on its The bisector is oriented in such a way that `p` lies on its
positive side. \pre `p` and `q` are not equal. positive side. \pre `p != q`.
*/ */
Kernel::Line_2 operator()(const Kernel::Point_2&p, Kernel::Line_2 operator()(const Kernel::Point_2&p,
const Kernel::Point_2&q ); const Kernel::Point_2&q );
@ -3920,7 +3920,7 @@ public:
/*! /*!
constructs the bisector plane of `p` and `q`. constructs the bisector plane of `p` and `q`.
The bisector is oriented in such a way that `p` lies on its The bisector is oriented in such a way that `p` lies on its
positive side. \pre `p` and `q` are not equal. positive side. \pre `p != q`.
*/ */
Kernel::Plane_3 operator()(const Kernel::Point_3&p, Kernel::Plane_3 operator()(const Kernel::Point_3&p,
const Kernel::Point_3&q ); const Kernel::Point_3&q );
@ -4200,7 +4200,7 @@ public:
It is initialized to the circle with center `center`, It is initialized to the circle with center `center`,
squared radius `squared_radius` and orientation squared radius `squared_radius` and orientation
`orientation`. `orientation`.
\pre `orientation` \f$ \neq\f$ \ref CGAL::COLLINEAR, and further, `squared_radius` \f$ \geq\f$ 0. \pre `orientation != CGAL::COLLINEAR` and `squared_radius >= 0`.
*/ */
Kernel::Circle_2 operator()( Kernel::Point_2 const& center, Kernel::Circle_2 operator()( Kernel::Point_2 const& center,
Kernel::FT const& squared_radius, Kernel::FT const& squared_radius,
@ -4225,7 +4225,7 @@ public:
introduces a variable of type `Kernel::Circle_2`. introduces a variable of type `Kernel::Circle_2`.
It is initialized to the circle with diameter `pq` It is initialized to the circle with diameter `pq`
and orientation `orientation`. and orientation `orientation`.
\pre `orientation` \f$ \neq\f$ \ref CGAL::COLLINEAR. \pre `orientation != CGAL::COLLINEAR`.
*/ */
Kernel::Circle_2 operator()( Kernel::Point_2 const& p, Kernel::Circle_2 operator()( Kernel::Point_2 const& p,
Kernel::Point_2 const& q, Kernel::Point_2 const& q,
@ -4237,7 +4237,7 @@ public:
introduces a variable of type `Kernel::Circle_2`. introduces a variable of type `Kernel::Circle_2`.
It is initialized to the circle with center `center`, squared It is initialized to the circle with center `center`, squared
radius zero and orientation `orientation`. radius zero and orientation `orientation`.
\pre `orientation` \f$ \neq\f$ \ref CGAL::COLLINEAR. \pre `orientation != CGAL::COLLINEAR`.
\post .`is_degenerate()` = `true`. \post .`is_degenerate()` = `true`.
*/ */
Kernel::Circle_2 operator()( Kernel::Point_2 const& center, Kernel::Circle_2 operator()( Kernel::Point_2 const& center,
@ -4269,7 +4269,7 @@ public:
introduces a variable of type `Kernel::Circle_3`. introduces a variable of type `Kernel::Circle_3`.
It is initialized to the circle with center `center`, It is initialized to the circle with center `center`,
and squared radius `sq_r` in the plane `plane`. and squared radius `sq_r` in the plane `plane`.
\pre `center` lies in `plane` and `sq_r` \f$ \geq\f$ 0. \pre `center` lies in `plane` and `sq_r >= 0`.
*/ */
Kernel::Circle_3 operator() Kernel::Circle_3 operator()
( Kernel::Point_3 const& center, ( Kernel::Point_3 const& center,
@ -4281,7 +4281,7 @@ public:
It is initialized to the circle with center `center`, It is initialized to the circle with center `center`,
and squared radius `sq_r` in the plane and squared radius `sq_r` in the plane
containing `center` and normal to `n`. containing `center` and normal to `n`.
\pre `sq_r` \f$ \geq\f$ 0. \pre `sq_r >= 0`.
*/ */
Kernel::Circle_3 operator() Kernel::Circle_3 operator()
( Kernel::Point_3 const& center, ( Kernel::Point_3 const& center,
@ -5637,7 +5637,7 @@ public:
introduces a direction orthogonal to `d`. If `o` is introduces a direction orthogonal to `d`. If `o` is
\ref CGAL::CLOCKWISE, `d` is rotated clockwise; if `o` is \ref CGAL::CLOCKWISE, `d` is rotated clockwise; if `o` is
\ref CGAL::COUNTERCLOCKWISE, `d` is rotated counterclockwise. \ref CGAL::COUNTERCLOCKWISE, `d` is rotated counterclockwise.
\pre `o` is not \ref CGAL::COLLINEAR. \pre `o != CGAL::COLLINEAR.`
*/ */
Kernel::Direction_2 operator()(const Kernel::Direction_2& d, Kernel::Direction_2 operator()(const Kernel::Direction_2& d,
Orientation o); Orientation o);
@ -5753,8 +5753,7 @@ public:
/*! /*!
returns `v` rotated clockwise by 90 degrees, if `o` is returns `v` rotated clockwise by 90 degrees, if `o` is
\ref CGAL::CLOCKWISE, and rotated counterclockwise otherwise. \ref CGAL::CLOCKWISE, and rotated counterclockwise otherwise.
\pre `o` is not \ref CGAL::COLLINEAR. \pre `o != CGAL::COLLINEAR`.
*/ */
Kernel::Vector_2 operator()(const Kernel::Vector_2& v, Kernel::Vector_2 operator()(const Kernel::Vector_2& v,
Orientation o); Orientation o);
@ -6580,7 +6579,7 @@ public:
introduces a sphere initialized to the sphere with center `center`, introduces a sphere initialized to the sphere with center `center`,
squared radius `squared_radius` and orientation squared radius `squared_radius` and orientation
`orientation`. `orientation`.
\pre `orientation` \f$ \neq\f$ \ref CGAL::COPLANAR, and furthermore, `squared_radius` \f$ \geq\f$ 0. \pre `orientation != CGAL::COPLANAR` and `squared_radius >= 0`.
*/ */
Kernel::Sphere_3 operator()(const Kernel::Point_3 & center, Kernel::Sphere_3 operator()(const Kernel::Point_3 & center,
const Kernel::FT & squared_radius, const Kernel::FT & squared_radius,
@ -6601,7 +6600,7 @@ public:
/*! /*!
introduces a sphere initialized to the smallest sphere which passes introduces a sphere initialized to the smallest sphere which passes
through the points `p`, `q`, and `r`. The orientation of through the points `p`, `q`, and `r`. The orientation of
the sphere is `o`. \pre `o` is not \ref CGAL::COPLANAR. the sphere is `o`. \pre `o != CGAL::COPLANAR`.
*/ */
Kernel::Sphere_3 operator()(const Kernel::Point_3 & p, Kernel::Sphere_3 operator()(const Kernel::Point_3 & p,
const Kernel::Point_3 & q, const Kernel::Point_3 & q,
@ -6611,7 +6610,7 @@ public:
/*! /*!
introduces a sphere initialized to the smallest sphere which passes introduces a sphere initialized to the smallest sphere which passes
through the points `p` and `q`. The orientation of through the points `p` and `q`. The orientation of
the sphere is `o`. \pre `o` is not \ref CGAL::COPLANAR. the sphere is `o`. \pre `o != CGAL::COPLANAR`.
*/ */
Kernel::Sphere_3 operator()(const Kernel::Point_3 & p, Kernel::Sphere_3 operator()(const Kernel::Point_3 & p,
const Kernel::Point_3 & q, const Kernel::Point_3 & q,
@ -6620,7 +6619,7 @@ public:
/*! /*!
introduces a sphere `s` initialized to the sphere with center introduces a sphere `s` initialized to the sphere with center
`center`, squared radius zero and orientation `orientation`. `center`, squared radius zero and orientation `orientation`.
\pre `orientation` \f$ \neq\f$ \ref CGAL::COPLANAR. \pre `orientation != CGAL::COPLANAR`.
\post `s.is_degenerate()` = `true`. \post `s.is_degenerate()` = `true`.
*/ */
Kernel::Sphere_3 operator()( const Kernel::Point_3 & center, Kernel::Sphere_3 operator()( const Kernel::Point_3 & center,

View File

@ -14,6 +14,7 @@
#define CGAL_PROJECTION_TRAITS_XY_3_H #define CGAL_PROJECTION_TRAITS_XY_3_H
#include <CGAL/Kernel_23/internal/Projection_traits_3.h> #include <CGAL/Kernel_23/internal/Projection_traits_3.h>
#include <CGAL/Triangulation_structural_filtering_traits.h>
namespace CGAL { namespace CGAL {
@ -22,6 +23,11 @@ class Projection_traits_xy_3
: public internal::Projection_traits_3<R,2> : public internal::Projection_traits_3<R,2>
{}; {};
template < class R >
struct Triangulation_structural_filtering_traits<Projection_traits_xy_3<R> > {
typedef typename Triangulation_structural_filtering_traits<R>::Use_structural_filtering_tag Use_structural_filtering_tag;
};
} //namespace CGAL } //namespace CGAL
#endif // CGAL_PROJECTION_TRAITS_XY_3_H #endif // CGAL_PROJECTION_TRAITS_XY_3_H

View File

@ -268,7 +268,7 @@ _test_cls_aff_transformation_2(const R& )
assert( pnt.transform(gat3).transform(gat2) == pnt.transform(co1) ); assert( pnt.transform(gat3).transform(gat2) == pnt.transform(co1) );
assert( dir.transform(gat3).transform(gat2) == dir.transform(co1) ); assert( dir.transform(gat3).transform(gat2) == dir.transform(co1) );
assert( vec.transform(gat3).transform(gat2) == vec.transform(co1) ); assert( vec.transform(gat3).transform(gat2) == vec.transform(co1) );
assert( lin.transform(gat3).transform(gat2) == lin.transform(co1) ); assert( lin.transform(gat3).transform(gat2) == lin.transform(co1) || nonexact);
co1 = ident * gat1; co1 = ident * gat1;
assert( vec.transform(gat1) == vec.transform(co1) ); assert( vec.transform(gat1) == vec.transform(co1) );
assert( dir.transform(gat1) == dir.transform(co1) ); assert( dir.transform(gat1) == dir.transform(co1) );
@ -281,7 +281,7 @@ _test_cls_aff_transformation_2(const R& )
assert( lin.transform(gat1) == lin.transform(co1) ); assert( lin.transform(gat1) == lin.transform(co1) );
co1 = gat1 * gat1.inverse() ; co1 = gat1 * gat1.inverse() ;
assert( vec == vec.transform(co1) ); assert( vec == vec.transform(co1) );
assert( pnt == pnt.transform(co1) ); assert( pnt == pnt.transform(co1) || nonexact);
assert( dir == dir.transform(co1) ); assert( dir == dir.transform(co1) );
assert( lin == lin.transform(co1) ); assert( lin == lin.transform(co1) );
@ -619,7 +619,7 @@ _test_cls_aff_transformation_2(const R& )
CGAL::Point_2<R>(1,3), CGAL::Point_2<R>(1,3),
CGAL::Point_2<R>(2,1))); CGAL::Point_2<R>(2,1)));
CGAL::Point_2<R> p(4,2); CGAL::Point_2<R> p(4,2);
assert(p.transform(refl) == CGAL::Point_2<R>(0,0)); assert(p.transform(refl) == CGAL::Point_2<R>(0,0) || nonexact);
//with translation //with translation
@ -642,7 +642,7 @@ _test_cls_aff_transformation_2(const R& )
assert(p1 == p.transform(comp1)); assert(p1 == p.transform(comp1));
p1 = p.transform(refl); p1 = p.transform(refl);
p1 = p1.transform(scal); p1 = p1.transform(scal);
assert(p1 == p.transform(comp2)); assert(p1 == p.transform(comp2) || nonexact);
//with rotation //with rotation
CGAL::Aff_transformation_2<R> rot(CGAL::ROTATION, 1, 0); CGAL::Aff_transformation_2<R> rot(CGAL::ROTATION, 1, 0);
comp1 = refl*rot; comp1 = refl*rot;
@ -652,7 +652,7 @@ _test_cls_aff_transformation_2(const R& )
assert(p1 == p.transform(comp1)); assert(p1 == p.transform(comp1));
p1 = p.transform(refl); p1 = p.transform(refl);
p1 = p1.transform(rot); p1 = p1.transform(rot);
assert(p1 == p.transform(comp2)); assert(p1 == p.transform(comp2) || nonexact);
//with reflection //with reflection
CGAL::Aff_transformation_2<R> refl2(CGAL::REFLECTION, CGAL::Line_2<R>( CGAL::Aff_transformation_2<R> refl2(CGAL::REFLECTION, CGAL::Line_2<R>(
CGAL::Point_2<R>(0,0), CGAL::Point_2<R>(0,0),
@ -664,7 +664,7 @@ _test_cls_aff_transformation_2(const R& )
assert(p1 == p.transform(comp1)); assert(p1 == p.transform(comp1));
p1 = p.transform(refl); p1 = p.transform(refl);
p1 = p1.transform(refl2); p1 = p1.transform(refl2);
assert(p1 == p.transform(comp2)); assert(p1 == p.transform(comp2) || nonexact);
//with transformation //with transformation
CGAL::Aff_transformation_2<R> afft(1,2,3,4,5,6); CGAL::Aff_transformation_2<R> afft(1,2,3,4,5,6);
comp1 = refl*afft; comp1 = refl*afft;
@ -674,7 +674,7 @@ _test_cls_aff_transformation_2(const R& )
assert(p1 == p.transform(comp1)); assert(p1 == p.transform(comp1));
p1 = p.transform(refl); p1 = p.transform(refl);
p1 = p1.transform(afft); p1 = p1.transform(afft);
assert(p1 == p.transform(comp2)); assert(p1 == p.transform(comp2) || nonexact);
//equality //equality
CGAL::Aff_transformation_2<R> a2(0,1,0,1), CGAL::Aff_transformation_2<R> a2(0,1,0,1),

View File

@ -88,11 +88,11 @@ _test_cls_sphere_3(const R& )
assert( cc != c8 ); assert( cc != c8 );
assert( cc == c7 ); assert( cc == c7 );
assert( c5.center() == p3 ); assert( c5.center() == p3 || nonexact);
assert( cc.center() == p3 ); assert( cc.center() == p3 );
assert( c5.squared_radius() == FT( n9 ) ); assert( c5.squared_radius() == FT( n9 ) );
assert( c4.squared_radius() == cc.squared_radius() ); assert( c4.squared_radius() == cc.squared_radius() );
assert( c4 == c5 ); assert( c4 == c5 || nonexact);
assert( c4 == c7 ); assert( c4 == c7 );
assert( c4 != c8 ); assert( c4 != c8 );
assert( cn == cp.opposite() ); assert( cn == cp.opposite() );
@ -114,7 +114,7 @@ _test_cls_sphere_3(const R& )
std::cout << '.'; std::cout << '.';
assert( c4.center() == p3 ); assert( c4.center() == p3 );
assert( c5.center() == p3 ); assert( c5.center() == p3 || nonexact);
assert( c4.squared_radius() == FT( n9 ) ); assert( c4.squared_radius() == FT( n9 ) );
assert( c5.squared_radius() == FT( n9 ) ); assert( c5.squared_radius() == FT( n9 ) );
assert( c8.squared_radius() == FT( n9 ) ); assert( c8.squared_radius() == FT( n9 ) );

View File

@ -92,7 +92,7 @@ _test_fct_points_implicit_sphere(const R&)
assert( CGAL::squared_distance( r, org ) == FT1 ); assert( CGAL::squared_distance( r, org ) == FT1 );
tpt = r.transform(rot_z); tpt = r.transform(rot_z);
assert( CGAL::squared_distance( tpt, org ) == FT1 ); assert( CGAL::squared_distance( tpt, org ) == FT1 || nonexact);
r = tpt.transform(rot_y); r = tpt.transform(rot_y);
assert( CGAL::squared_distance( r, org ) == FT1 || nonexact ); assert( CGAL::squared_distance( r, org ) == FT1 || nonexact );

View File

@ -68,11 +68,11 @@ _test_mf_plane_3_to_2d(const R& )
Point_3 p6( n4, n5, n0, n8); Point_3 p6( n4, n5, n0, n8);
Plane_3 pl3( p4, p5, p6); Plane_3 pl3( p4, p5, p6);
assert( p4 == pl3.to_3d( pl3.to_2d( p4)) || nonexact ); assert( p4 == pl3.to_3d( pl3.to_2d( p4)) || nonexact );
assert( p5 == pl3.to_3d( pl3.to_2d( p5)) ); assert( p5 == pl3.to_3d( pl3.to_2d( p5)) || nonexact);
assert( p6 == pl3.to_3d( pl3.to_2d( p6)) || nonexact ); assert( p6 == pl3.to_3d( pl3.to_2d( p6)) || nonexact );
Plane_3 pl4( p4, p6, p5); Plane_3 pl4( p4, p6, p5);
assert( p4 == pl4.to_3d( pl4.to_2d( p4)) || nonexact ); assert( p4 == pl4.to_3d( pl4.to_2d( p4)) || nonexact );
assert( p5 == pl4.to_3d( pl4.to_2d( p5)) ); assert( p5 == pl4.to_3d( pl4.to_2d( p5)) || nonexact);
assert( p6 == pl4.to_3d( pl4.to_2d( p6)) || nonexact ); assert( p6 == pl4.to_3d( pl4.to_2d( p6)) || nonexact );
Point_3 p7 = CGAL::midpoint( p1, p2); Point_3 p7 = CGAL::midpoint( p1, p2);

View File

@ -740,7 +740,11 @@ template <typename GT, typename MD>
class Compact_mesh_cell_base_3<GT, MD, void> class Compact_mesh_cell_base_3<GT, MD, void>
{ {
public: public:
#ifdef DOXYGEN_RUNNING
typedef unspecified_type Triangulation_data_structure;
#else
typedef internal::Dummy_tds_3 Triangulation_data_structure; typedef internal::Dummy_tds_3 Triangulation_data_structure;
#endif
typedef Triangulation_data_structure::Vertex_handle Vertex_handle; typedef Triangulation_data_structure::Vertex_handle Vertex_handle;
typedef Triangulation_data_structure::Cell_handle Cell_handle; typedef Triangulation_data_structure::Cell_handle Cell_handle;
template <typename TDS2> template <typename TDS2>
@ -761,7 +765,11 @@ template <typename GT,
class Compact_mesh_cell_generator_3 class Compact_mesh_cell_generator_3
{ {
public: public:
#ifdef DOXYGEN_RUNNING
typedef unspecified_type Triangulation_data_structure;
#else
typedef internal::Dummy_tds_3 Triangulation_data_structure; typedef internal::Dummy_tds_3 Triangulation_data_structure;
#endif
typedef Triangulation_data_structure::Vertex_handle Vertex_handle; typedef Triangulation_data_structure::Vertex_handle Vertex_handle;
typedef Triangulation_data_structure::Cell_handle Cell_handle; typedef Triangulation_data_structure::Cell_handle Cell_handle;
template <typename TDS2> template <typename TDS2>

View File

@ -974,7 +974,7 @@ update_mesh(const Moves_vector& moves,
{ {
FT size = std::get<2>(*it); FT size = std::get<2>(*it);
#ifdef CGAL_MESH_3_OPTIMIZER_VERBOSE #ifdef CGAL_MESH_3_OPTIMIZER_VERY_VERBOSE
std::cerr << "Moving #" << it - moves.begin() std::cerr << "Moving #" << it - moves.begin()
<< " addr: " << &*v << " addr: " << &*v
<< " pt: " << tr_.point(v) << " pt: " << tr_.point(v)

View File

@ -575,7 +575,7 @@ refine_mesh(std::string dump_after_refine_surface_prefix)
nbsteps = 0; nbsteps = 0;
facets_visitor_.activate(); facets_visitor_.activate();
dump_c3t3(r_c3t3_, dump_after_refine_surface_prefix);
std::cerr << "Start volume scan..."; std::cerr << "Start volume scan...";
CGAL_MESH_3_TASK_BEGIN(scan_cells_task_handle); CGAL_MESH_3_TASK_BEGIN(scan_cells_task_handle);
cells_mesher_.scan_triangulation(); cells_mesher_.scan_triangulation();
@ -584,6 +584,7 @@ refine_mesh(std::string dump_after_refine_surface_prefix)
std::cerr << "end scan. [Bad tets:" << cells_mesher_.size() << "]"; std::cerr << "end scan. [Bad tets:" << cells_mesher_.size() << "]";
std::cerr << std::endl << std::endl; std::cerr << std::endl << std::endl;
elapsed_time += timer.time(); elapsed_time += timer.time();
dump_c3t3(r_c3t3_, dump_after_refine_surface_prefix);
timer.stop(); timer.reset(); timer.start(); timer.stop(); timer.reset(); timer.start();
std::cerr << "Refining...\n"; std::cerr << "Refining...\n";
@ -690,7 +691,8 @@ initialize()
# ifdef CGAL_CONCURRENT_MESH_3_VERBOSE # ifdef CGAL_CONCURRENT_MESH_3_VERBOSE
std::cerr << "Adding points on a far sphere (radius = " << radius <<")..."; std::cerr << "Adding points on a far sphere (radius = " << radius <<")...";
# endif # endif
Random_points_on_sphere_3<Bare_point> random_point(radius); CGAL::Random rnd(0);
Random_points_on_sphere_3<Bare_point> random_point(radius, rnd);
const int NUM_PSEUDO_INFINITE_VERTICES = static_cast<int>( const int NUM_PSEUDO_INFINITE_VERTICES = static_cast<int>(
float(std::thread::hardware_concurrency()) float(std::thread::hardware_concurrency())
* Concurrent_mesher_config::get().num_pseudo_infinite_vertices_per_core); * Concurrent_mesher_config::get().num_pseudo_infinite_vertices_per_core);

View File

@ -57,4 +57,10 @@
# endif # endif
#endif #endif
#ifdef CGAL_MESH_3_VERY_VERBOSE
# ifndef CGAL_MESH_3_OPTIMIZER_VERY_VERBOSE
# define CGAL_MESH_3_OPTIMIZER_VERY_VERBOSE 1
# endif
#endif
#endif // CGAL_MESH_3_CONFIG_H #endif // CGAL_MESH_3_CONFIG_H

View File

@ -152,7 +152,9 @@ void initialize_triangulation_from_labeled_image(C3T3& c3t3,
const Subdomain seed_label const Subdomain seed_label
= domain.is_in_domain_object()(seed_point); = domain.is_in_domain_object()(seed_point);
const Subdomain seed_cell_label const Subdomain seed_cell_label
= (seed_cell == Cell_handle() || tr.is_infinite(seed_cell)) = ( tr.dimension() < 3
|| seed_cell == Cell_handle()
|| tr.is_infinite(seed_cell))
? Subdomain() //seed_point is OUTSIDE_AFFINE_HULL ? Subdomain() //seed_point is OUTSIDE_AFFINE_HULL
: domain.is_in_domain_object()( : domain.is_in_domain_object()(
seed_cell->weighted_circumcenter(tr.geom_traits())); seed_cell->weighted_circumcenter(tr.geom_traits()));

View File

@ -549,11 +549,15 @@ public:
typedef int Curve_index; typedef int Curve_index;
typedef int Corner_index; typedef int Corner_index;
#ifdef DOXYGEN_RUNNING
typedef unspecified_type Index;
#else
typedef typename Mesh_3::internal::Index_generator_with_features< typedef typename Mesh_3::internal::Index_generator_with_features<
typename MeshDomain_3::Subdomain_index, typename MeshDomain_3::Subdomain_index,
Surface_patch_index, Surface_patch_index,
Curve_index, Curve_index,
Corner_index>::type Index; Corner_index>::type Index;
#endif
typedef CGAL::Tag_true Has_features; typedef CGAL::Tag_true Has_features;
typedef typename MeshDomain_3::R::FT FT; typedef typename MeshDomain_3::R::FT FT;

View File

@ -317,7 +317,11 @@ template<class GT,
class MD, class MD,
class Vb = Regular_triangulation_vertex_base_3<GT> > class Vb = Regular_triangulation_vertex_base_3<GT> >
struct Mesh_vertex_base_3 { struct Mesh_vertex_base_3 {
#ifdef DOXYGEN_RUNNING
using Triangulation_data_structure = unspecified_type;
#else
using Triangulation_data_structure = internal::Dummy_tds_3; using Triangulation_data_structure = internal::Dummy_tds_3;
#endif
using Vertex_handle = typename Triangulation_data_structure::Vertex_handle; using Vertex_handle = typename Triangulation_data_structure::Vertex_handle;
using Cell_handle = typename Triangulation_data_structure::Cell_handle; using Cell_handle = typename Triangulation_data_structure::Cell_handle;
@ -335,7 +339,11 @@ template<class GT,
class Index, class Index,
class Vb = Regular_triangulation_vertex_base_3<GT> > class Vb = Regular_triangulation_vertex_base_3<GT> >
struct Mesh_vertex_generator_3 { struct Mesh_vertex_generator_3 {
#ifdef DOXYGEN_RUNNING
using Triangulation_data_structure = unspecified_type;
#else
using Triangulation_data_structure = internal::Dummy_tds_3; using Triangulation_data_structure = internal::Dummy_tds_3;
#endif
using Vertex_handle = typename Triangulation_data_structure::Vertex_handle; using Vertex_handle = typename Triangulation_data_structure::Vertex_handle;
using Cell_handle = typename Triangulation_data_structure::Cell_handle; using Cell_handle = typename Triangulation_data_structure::Cell_handle;

View File

@ -48,6 +48,7 @@ if ( CGAL_FOUND )
create_single_source_cgal_program( "test_meshing_unit_tetrahedron.cpp" ) create_single_source_cgal_program( "test_meshing_unit_tetrahedron.cpp" )
create_single_source_cgal_program( "test_meshing_with_default_edge_size.cpp" ) create_single_source_cgal_program( "test_meshing_with_default_edge_size.cpp" )
create_single_source_cgal_program( "test_meshing_determinism.cpp" ) create_single_source_cgal_program( "test_meshing_determinism.cpp" )
create_single_source_cgal_program( "test_meshing_without_features_determinism.cpp" )
create_single_source_cgal_program( "test_mesh_3_issue_1554.cpp" ) create_single_source_cgal_program( "test_mesh_3_issue_1554.cpp" )
create_single_source_cgal_program( "test_mesh_polyhedral_domain_with_features_deprecated.cpp" ) create_single_source_cgal_program( "test_mesh_polyhedral_domain_with_features_deprecated.cpp" )
create_single_source_cgal_program( "test_meshing_with_one_step.cpp" ) create_single_source_cgal_program( "test_meshing_with_one_step.cpp" )
@ -76,6 +77,7 @@ if ( CGAL_FOUND )
test_meshing_unit_tetrahedron test_meshing_unit_tetrahedron
test_meshing_with_default_edge_size test_meshing_with_default_edge_size
test_meshing_determinism test_meshing_determinism
test_meshing_without_features_determinism
test_mesh_3_issue_1554 test_mesh_3_issue_1554
test_mesh_polyhedral_domain_with_features_deprecated test_mesh_polyhedral_domain_with_features_deprecated
test_mesh_cell_base_3 test_mesh_cell_base_3
@ -97,6 +99,8 @@ if ( CGAL_FOUND )
test_meshing_polyhedron test_meshing_polyhedron
test_meshing_polyhedral_complex test_meshing_polyhedral_complex
test_mesh_capsule_var_distance_bound test_mesh_capsule_var_distance_bound
test_meshing_determinism
test_meshing_without_features_determinism
test_mesh_3_issue_1554 test_mesh_3_issue_1554
test_mesh_polyhedral_domain_with_features_deprecated test_mesh_polyhedral_domain_with_features_deprecated
test_mesh_cell_base_3 test_mesh_cell_base_3

View File

@ -68,7 +68,10 @@ void test()
// iterate // iterate
std::vector<std::string> output_c3t3; std::vector<std::string> output_c3t3;
std::vector<std::string> output_surfaces; std::vector<std::string> output_surfaces;
output_c3t3.reserve(5 * nb_runs);
const std::size_t nb_operations = 5;
output_c3t3.reserve(nb_operations * nb_runs);
for(std::size_t i = 0; i < nb_runs; ++i) for(std::size_t i = 0; i < nb_runs; ++i)
{ {
std::cout << "------- Iteration " << (i+1) << " -------" << std::endl; std::cout << "------- Iteration " << (i+1) << " -------" << std::endl;
@ -133,14 +136,16 @@ void test()
if(i == 0) if(i == 0)
continue; continue;
//else check //else check
for(std::size_t j = 0; j < 5; ++j) for(std::size_t j = 0; j < nb_operations; ++j)
{ {
if(0 != output_c3t3[5*(i-1)+j].compare(output_c3t3[5*i+j])) std::size_t id1 = nb_operations * (i - 1) + j;
std::size_t id2 = nb_operations * i + j;
if(0 != output_c3t3[id1].compare(output_c3t3[id2]))
{ {
std::cerr << "Meshing operation " << j << " is not deterministic.\n"; std::cerr << "Meshing operation " << j << " is not deterministic.\n";
assert(false); assert(false);
} }
if (0 != output_surfaces[5 * (i - 1) + j].compare(output_surfaces[5 * i + j])) if (0 != output_surfaces[id1].compare(output_surfaces[id2]))
{ {
std::cerr << "Output surface after operation " << j << " is not deterministic.\n"; std::cerr << "Output surface after operation " << j << " is not deterministic.\n";
assert(false); assert(false);
@ -151,8 +156,11 @@ void test()
int main(int, char*[]) int main(int, char*[])
{ {
std::cout << "Sequential test" << std::endl;
test<CGAL::Sequential_tag>(); test<CGAL::Sequential_tag>();
#ifdef CGAL_LINKED_WITH_TBB #ifdef CGAL_LINKED_WITH_TBB
std::cout << "\n\nParallel with 1 thread test" << std::endl;
tbb::global_control c(tbb::global_control::max_allowed_parallelism, 1); tbb::global_control c(tbb::global_control::max_allowed_parallelism, 1);
test<CGAL::Parallel_tag>(); test<CGAL::Parallel_tag>();
#endif #endif

View File

@ -0,0 +1,160 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Mesh_triangulation_3.h>
#include <CGAL/Mesh_polyhedron_3.h>
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
#include <CGAL/Mesh_criteria_3.h>
#include <CGAL/Polyhedral_mesh_domain_3.h>
#include <CGAL/make_mesh_3.h>
#include <CGAL/lloyd_optimize_mesh_3.h>
#include <CGAL/odt_optimize_mesh_3.h>
#include <CGAL/perturb_mesh_3.h>
#include <CGAL/exude_mesh_3.h>
#include <CGAL/facets_in_complex_3_to_triangle_mesh.h>
#include <cassert>
#include <fstream>
#include <sstream>
#include <cstring>
#ifdef CGAL_LINKED_WITH_TBB
#define TBB_PREVIEW_GLOBAL_CONTROL 1
# include <tbb/global_control.h>
#endif
// To avoid verbose function and named parameters call
using namespace CGAL::parameters;
template <typename Concurrency_tag>
void test()
{
// Collect options
std::size_t nb_runs = 2;
unsigned int nb_lloyd = 2;
unsigned int nb_odt = 2;
double perturb_bound = 10.;
double exude_bound = 15.;
// Domain
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Mesh_polyhedron_3<K>::type Polyhedron;
typedef CGAL::Polyhedral_mesh_domain_3<Polyhedron,K> Mesh_domain;
// Triangulation
typedef typename CGAL::Mesh_triangulation_3<Mesh_domain, K, Concurrency_tag>::type Tr;
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
// Mesh Criteria
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria;
// Domain
std::cout << "\tSeed is\t 0" << std::endl;
std::ifstream input(CGAL::data_file_path("meshes/cube.off"));
Polyhedron polyhedron;
input >> polyhedron;
Mesh_domain domain(polyhedron);
//no random generator is given, so CGAL::Random(0) is used
// Mesh criteria
Mesh_criteria criteria(edge_size = 0.2,
facet_angle = 25,
facet_size = 0.2,
facet_distance = 0.002,
cell_radius_edge_ratio = 3,
cell_size = 0.2);
// iterate
std::vector<std::string> output_c3t3;
std::vector<std::string> output_surfaces;
output_c3t3.reserve(5 * nb_runs);
for(std::size_t i = 0; i < nb_runs; ++i)
{
std::cout << "------- Iteration " << (i+1) << " -------" << std::endl;
C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria,
no_perturb(),
no_exude());
std::ostringstream oss;
CGAL::IO::write_MEDIT(oss, c3t3);
output_c3t3.push_back(oss.str()); //[5*i]
oss.clear();
Polyhedron out_poly;
CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, out_poly);
oss << out_poly;
output_surfaces.push_back(oss.str());//[5*i]
out_poly.clear();
oss.clear();
//LLOYD (1)
CGAL::lloyd_optimize_mesh_3(c3t3, domain, max_iteration_number = nb_lloyd);
CGAL::IO::write_MEDIT(oss, c3t3);
output_c3t3.push_back(oss.str());//[i*5+1]
oss.clear();
CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, out_poly);
oss << out_poly;
output_surfaces.push_back(oss.str());//[i*5+1]
out_poly.clear();
oss.clear();
//ODT (2)
CGAL::odt_optimize_mesh_3(c3t3, domain, max_iteration_number = nb_odt);
CGAL::IO::write_MEDIT(oss, c3t3);
output_c3t3.push_back(oss.str());//[i*5+2]
oss.clear();
CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, out_poly);
oss << out_poly;
output_surfaces.push_back(oss.str());//[i*5+2]
out_poly.clear();
oss.clear();
//PERTURB (3)
CGAL::perturb_mesh_3(c3t3, domain, sliver_bound=perturb_bound);
CGAL::IO::write_MEDIT(oss, c3t3);
output_c3t3.push_back(oss.str());//[i*5+3]
oss.clear();
CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, out_poly);
oss << out_poly;
output_surfaces.push_back(oss.str());//[i*5+3]
out_poly.clear();
oss.clear();
//EXUDE (4)
CGAL::exude_mesh_3(c3t3, sliver_bound=exude_bound);
CGAL::IO::write_MEDIT(oss, c3t3);
output_c3t3.push_back(oss.str());//[i*5+4]
oss.clear();
CGAL::facets_in_complex_3_to_triangle_mesh(c3t3, out_poly);
oss << out_poly;
output_surfaces.push_back(oss.str());//[i*5+4]
out_poly.clear();
oss.clear();
if(i == 0)
continue;
//else check
for(std::size_t j = 0; j < 5; ++j)
{
if(0 != output_c3t3[5*(i-1)+j].compare(output_c3t3[5*i+j]))
{
std::cerr << "Meshing operation " << j << " is not deterministic.\n";
assert(false);
}
if (0 != output_surfaces[5 * (i - 1) + j].compare(output_surfaces[5 * i + j]))
{
std::cerr << "Output surface after operation " << j << " is not deterministic.\n";
assert(false);
}
}
}
}
int main(int, char*[])
{
std::cout << "Sequential test" << std::endl;
test<CGAL::Sequential_tag>();
#ifdef CGAL_LINKED_WITH_TBB
std::cout << "\n\nParallel with 1 thread test" << std::endl;
tbb::global_control c(tbb::global_control::max_allowed_parallelism, 1);
test<CGAL::Parallel_tag>();
#endif
}

View File

@ -32,8 +32,7 @@ namespace CGAL {
// This implementation is based on Alon Baram's 2013 master's thesis "Polygonal // This implementation is based on Alon Baram's 2013 master's thesis "Polygonal
// Minkowski Sums via Convolution: Theory and Practice" at Tel-Aviv University. // Minkowski Sums via Convolution: Theory and Practice" at Tel-Aviv University.
template <typename Kernel_, typename Container_> template <typename Kernel_, typename Container_>
class Minkowski_sum_by_reduced_convolution_2 class Minkowski_sum_by_reduced_convolution_2 {
{
private: private:
typedef Kernel_ Kernel; typedef Kernel_ Kernel;
typedef Container_ Container; typedef Container_ Container;
@ -56,14 +55,14 @@ private:
// Arrangement-related types: // Arrangement-related types:
typedef Arrangement_with_history_2<Traits_2, Dcel> Arrangement_history_2; typedef Arrangement_with_history_2<Traits_2, Dcel> Arrangement_history_2;
typedef typename Arrangement_history_2::Halfedge_handle Halfedge_handle; typedef typename Arrangement_history_2::Halfedge_const_handle
typedef typename Arrangement_history_2::Face_iterator Face_iterator; Halfedge_const_handle;
typedef typename Arrangement_history_2::Face_handle Face_handle; typedef typename Arrangement_history_2::Face_const_handle
typedef typename Arrangement_history_2::Ccb_halfedge_circulator Face_const_handle;
Ccb_halfedge_circulator; typedef typename Arrangement_history_2::Ccb_halfedge_const_circulator
typedef typename Arrangement_history_2::Originating_curve_iterator Ccb_halfedge_const_circulator;
Originating_curve_iterator; typedef typename Arrangement_history_2::Inner_ccb_const_iterator
typedef typename Arrangement_history_2::Inner_ccb_iterator Inner_ccb_iterator; Inner_ccb_const_iterator;
// Function object types: // Function object types:
typename Kernel::Construct_translated_point_2 f_add; typename Kernel::Construct_translated_point_2 f_add;
@ -74,8 +73,8 @@ private:
typename Kernel::Counterclockwise_in_between_2 f_ccw_in_between; typename Kernel::Counterclockwise_in_between_2 f_ccw_in_between;
public: public:
Minkowski_sum_by_reduced_convolution_2() //! \brief constructs.
{ Minkowski_sum_by_reduced_convolution_2() {
// Obtain kernel functors // Obtain kernel functors
Kernel ker; Kernel ker;
f_add = ker.construct_translated_point_2_object(); f_add = ker.construct_translated_point_2_object();
@ -86,10 +85,10 @@ public:
f_ccw_in_between = ker.counterclockwise_in_between_2_object(); f_ccw_in_between = ker.counterclockwise_in_between_2_object();
} }
//! \brief applies the Minkowski sum reduced-convolution operator.
template <typename OutputIterator> template <typename OutputIterator>
void operator()(const Polygon_2& pgn1, const Polygon_2& pgn2, void operator()(const Polygon_2& pgn1, const Polygon_2& pgn2,
Polygon_2& outer_boundary, OutputIterator holes) const Polygon_2& outer_boundary, OutputIterator holes) const {
{
CGAL_precondition(pgn1.is_simple()); CGAL_precondition(pgn1.is_simple());
CGAL_precondition(pgn2.is_simple()); CGAL_precondition(pgn2.is_simple());
CGAL_precondition(pgn1.orientation() == COUNTERCLOCKWISE); CGAL_precondition(pgn1.orientation() == COUNTERCLOCKWISE);
@ -101,19 +100,17 @@ public:
common_operator(pwh1, pwh2, outer_boundary, holes); common_operator(pwh1, pwh2, outer_boundary, holes);
} }
//! \brief applies the Minkowski sum reduced-convolution operator.
template <typename OutputIterator> template <typename OutputIterator>
void operator()(const Polygon_with_holes_2& pgn1, void operator()(const Polygon_with_holes_2& pgn1,
const Polygon_with_holes_2& pgn2, const Polygon_with_holes_2& pgn2,
Polygon_2& outer_boundary, OutputIterator holes) const Polygon_2& outer_boundary, OutputIterator holes) const
{ { common_operator(pgn1, pgn2, outer_boundary, holes); }
common_operator(pgn1, pgn2, outer_boundary, holes);
}
//! \brief applies the Minkowski sum reduced-convolution operator.
template <typename OutputIterator> template <typename OutputIterator>
void operator()(const Polygon_2& pgn1, void operator()(const Polygon_2& pgn1, const Polygon_with_holes_2& pgn2,
const Polygon_with_holes_2& pgn2, Polygon_2& outer_boundary, OutputIterator holes) const {
Polygon_2& outer_boundary, OutputIterator holes) const
{
CGAL_precondition(pgn1.is_simple()); CGAL_precondition(pgn1.is_simple());
CGAL_precondition(pgn1.orientation() == COUNTERCLOCKWISE); CGAL_precondition(pgn1.orientation() == COUNTERCLOCKWISE);
const Polygon_with_holes_2 pwh1(pgn1); const Polygon_with_holes_2 pwh1(pgn1);
@ -121,11 +118,11 @@ public:
} }
private: private:
//! \brief applies the Minkowski sum reduced-convolution operator.
template <typename OutputIterator> template <typename OutputIterator>
void common_operator(const Polygon_with_holes_2& pgn1, void common_operator(const Polygon_with_holes_2& pgn1,
const Polygon_with_holes_2& pgn2, const Polygon_with_holes_2& pgn2,
Polygon_2& outer_boundary, OutputIterator holes) const Polygon_2& outer_boundary, OutputIterator holes) const {
{
// If the outer boundaries of both summands are empty the Minkowski sum is // If the outer boundaries of both summands are empty the Minkowski sum is
// the entire plane. // the entire plane.
if (pgn1.outer_boundary().is_empty() && pgn2.outer_boundary().is_empty()) if (pgn1.outer_boundary().is_empty() && pgn2.outer_boundary().is_empty())
@ -157,7 +154,7 @@ private:
// Check for each face whether it is a hole in the M-sum. If it is, add it // Check for each face whether it is a hole in the M-sum. If it is, add it
// to 'holes'. See chapter 3 of of Alon's master's thesis. // to 'holes'. See chapter 3 of of Alon's master's thesis.
for (Face_iterator fit = arr.faces_begin(); fit != arr.faces_end(); ++fit) { for (auto fit = arr.faces_begin(); fit != arr.faces_end(); ++fit) {
// Check whether the face is on the M-sum's border. // Check whether the face is on the M-sum's border.
// The unbounded face cannot contribute to the Minkowski sum // The unbounded face cannot contribute to the Minkowski sum
@ -169,8 +166,8 @@ private:
// The face needs to be orientable // The face needs to be orientable
if (! test_face_orientation(arr, fit)) continue; if (! test_face_orientation(arr, fit)) continue;
// When the reversed polygon 1, translated by a point inside of this face, // When the reversed polygon 1, translated by a point inside of this
// collides with polygon 2, this cannot be a hole // face, collides with polygon 2, this cannot be a hole
Point_2 inner_point = get_point_in_face(fit); Point_2 inner_point = get_point_in_face(fit);
if (collision_detector.check_collision(inner_point)) continue; if (collision_detector.check_collision(inner_point)) continue;
@ -178,56 +175,52 @@ private:
} }
} }
// Builds the reduced convolution for each pair of loop in the two /*! \brief builds the reduced convolution for each pair of loops in the two
// polygons-with-holes. * polygons-with-holes.
*/
void build_reduced_convolution(const Polygon_with_holes_2& pgnwh1, void build_reduced_convolution(const Polygon_with_holes_2& pgnwh1,
const Polygon_with_holes_2& pgnwh2, const Polygon_with_holes_2& pgnwh2,
Segment_list& reduced_convolution) const Segment_list& reduced_convolution) const {
{ for (std::size_t x = 0; x < 1+pgnwh1.number_of_holes(); ++x) {
for (std::size_t x = 0; x < 1+pgnwh1.number_of_holes(); ++x) for (std::size_t y = 0; y < 1+pgnwh2.number_of_holes(); ++y) {
{ if ((x != 0) && (y != 0)) continue;
for (std::size_t y = 0; y < 1+pgnwh2.number_of_holes(); ++y)
{
if ((x != 0) && (y != 0))
{
continue;
}
Polygon_2 pgn1, pgn2;
if (x == 0) { if (x == 0) {
pgn1 = pgnwh1.outer_boundary(); const auto& pgn1 = pgnwh1.outer_boundary();
}
else {
typename Polygon_with_holes_2::Hole_const_iterator it1 =
pgnwh1.holes_begin();
for (std::size_t count = 0; count < x-1; count++) { it1++; }
pgn1 = *it1;
}
if (y == 0) { if (y == 0) {
pgn2 = pgnwh2.outer_boundary(); const auto& pgn2 = pgnwh2.outer_boundary();
}
else {
typename Polygon_with_holes_2::Hole_const_iterator it2 =
pgnwh2.holes_begin();
for (std::size_t count = 0; count < y-1; count++) { it2++; }
pgn2 = *it2;
}
build_reduced_convolution(pgn1, pgn2, reduced_convolution); build_reduced_convolution(pgn1, pgn2, reduced_convolution);
} }
else {
auto it2 = pgnwh2.holes_begin();
for (std::size_t count = 0; count < y-1; ++count) ++it2;
build_reduced_convolution(pgn1, *it2, reduced_convolution);
}
}
else {
auto it1 = pgnwh1.holes_begin();
for (std::size_t count = 0; count < x-1; ++count) ++it1;
if (y == 0) {
const auto& pgn2 = pgnwh2.outer_boundary();
build_reduced_convolution(*it1, pgn2, reduced_convolution);
}
else {
auto it2 = pgnwh2.holes_begin();
for (std::size_t count = 0; count < y-1; ++count) ++it2;
build_reduced_convolution(*it1, *it2, reduced_convolution);
}
}
}
} }
} }
// Builds the reduced convolution using a fiber grid approach. For each /*! \brief builds the reduced convolution using a fiber grid approach. For
// starting vertex, try to add two outgoing next states. If a visited * each starting vertex, try to add two outgoing next states. If a visited
// vertex is reached, then do not explore further. This is a BFS-like * vertex is reached, then do not explore further. This is a BFS-like
// iteration beginning from each vertex in the first column of the fiber * iteration beginning from each vertex in the first column of the fiber
// grid. * grid.
*/
void build_reduced_convolution(const Polygon_2& pgn1, const Polygon_2& pgn2, void build_reduced_convolution(const Polygon_2& pgn1, const Polygon_2& pgn2,
Segment_list& reduced_convolution) const Segment_list& reduced_convolution) const {
{
int n1 = static_cast<int>(pgn1.size()); int n1 = static_cast<int>(pgn1.size());
int n2 = static_cast<int>(pgn2.size()); int n2 = static_cast<int>(pgn2.size());
if ((n1 == 0) || (n2 == 0)) return; if ((n1 == 0) || (n2 == 0)) return;
@ -244,13 +237,9 @@ private:
// Init the queue with vertices from the first column // Init the queue with vertices from the first column
std::queue<State> state_queue; std::queue<State> state_queue;
for (int i = n1-1; i >= 0; --i) for (int i = n1-1; i >= 0; --i) state_queue.push(State(i, 0));
{
state_queue.push(State(i, 0));
}
while (state_queue.size() > 0) while (state_queue.size() > 0) {
{
State curr_state = state_queue.front(); State curr_state = state_queue.front();
state_queue.pop(); state_queue.pop();
@ -258,10 +247,7 @@ private:
int i2 = curr_state.second; int i2 = curr_state.second;
// If this state was already visited, skip it // If this state was already visited, skip it
if (visited_states.count(curr_state) > 0) if (visited_states.count(curr_state) > 0) continue;
{
continue;
}
visited_states.insert(curr_state); visited_states.insert(curr_state);
int next_i1 = (i1+1) % n1; int next_i1 = (i1+1) % n1;
@ -271,16 +257,13 @@ private:
// Try two transitions: From (i,j) to (i+1,j) and to (i,j+1). Add // Try two transitions: From (i,j) to (i+1,j) and to (i,j+1). Add
// the respective segments, if they are in the reduced convolution. // the respective segments, if they are in the reduced convolution.
for(int step_in_pgn1 = 0; step_in_pgn1 <= 1; step_in_pgn1++) for (int step_in_pgn1 = 0; step_in_pgn1 <= 1; ++step_in_pgn1) {
{
int new_i1, new_i2; int new_i1, new_i2;
if (step_in_pgn1) if (step_in_pgn1) {
{
new_i1 = next_i1; new_i1 = next_i1;
new_i2 = i2; new_i2 = i2;
} }
else else {
{
new_i1 = i1; new_i1 = i1;
new_i2 = next_i2; new_i2 = next_i2;
} }
@ -289,39 +272,33 @@ private:
// the other polygon's vertex' ingoing and outgoing directions, // the other polygon's vertex' ingoing and outgoing directions,
// the segment belongs to the full convolution. // the segment belongs to the full convolution.
bool belongs_to_convolution; bool belongs_to_convolution;
if (step_in_pgn1) if (step_in_pgn1) {
{
belongs_to_convolution = belongs_to_convolution =
f_ccw_in_between(p1_dirs[i1], p2_dirs[prev_i2], p2_dirs[i2]) || f_ccw_in_between(p1_dirs[i1], p2_dirs[prev_i2], p2_dirs[i2]) ||
p1_dirs[i1] == p2_dirs[i2]; p1_dirs[i1] == p2_dirs[i2];
} }
else else {
{
belongs_to_convolution = belongs_to_convolution =
f_ccw_in_between(p2_dirs[i2], p1_dirs[prev_i1], p1_dirs[i1]) || f_ccw_in_between(p2_dirs[i2], p1_dirs[prev_i1], p1_dirs[i1]) ||
p2_dirs[i2] == p1_dirs[prev_i1]; p2_dirs[i2] == p1_dirs[prev_i1];
} }
if (belongs_to_convolution) if (belongs_to_convolution) {
{
state_queue.push(State(new_i1, new_i2)); state_queue.push(State(new_i1, new_i2));
// Only edges added to convex vertices can be on the M-sum's boundary. // Only edges added to convex vertices can be on the M-sum's boundary.
// This filter only leaves the *reduced* convolution. // This filter only leaves the *reduced* convolution.
bool convex; bool convex;
if (step_in_pgn1) if (step_in_pgn1) {
{
convex = is_convex(p2_vertices[prev_i2], p2_vertices[i2], convex = is_convex(p2_vertices[prev_i2], p2_vertices[i2],
p2_vertices[next_i2]); p2_vertices[next_i2]);
} }
else else {
{
convex = is_convex(p1_vertices[prev_i1], p1_vertices[i1], convex = is_convex(p1_vertices[prev_i1], p1_vertices[i1],
p1_vertices[next_i1]); p1_vertices[next_i1]);
} }
if (convex) if (convex) {
{
Point_2 start_point = get_point(i1, i2, p1_vertices, p2_vertices); Point_2 start_point = get_point(i1, i2, p1_vertices, p2_vertices);
Point_2 end_point = get_point(new_i1, new_i2, p1_vertices, Point_2 end_point = get_point(new_i1, new_i2, p1_vertices,
p2_vertices); p2_vertices);
@ -334,27 +311,21 @@ private:
// Returns a vector of the polygon's vertices, in case that Container // Returns a vector of the polygon's vertices, in case that Container
// is std::list and we cannot use vertex(i). // is std::list and we cannot use vertex(i).
std::vector<Point_2> vertices_of_polygon(const Polygon_2& p) const std::vector<Point_2> vertices_of_polygon(const Polygon_2& p) const {
{
std::vector<Point_2> vertices; std::vector<Point_2> vertices;
for (typename Polygon_2::Vertex_const_iterator it = p.vertices_begin(); for (auto it = p.vertices_begin(); it != p.vertices_end(); it++)
it != p.vertices_end(); it++)
{
vertices.push_back(*it); vertices.push_back(*it);
}
return vertices; return vertices;
} }
// Returns a sorted list of the polygon's edges // Returns a sorted list of the polygon's edges
std::vector<Direction_2> directions_of_polygon( std::vector<Direction_2>
const std::vector<Point_2>& points) const directions_of_polygon(const std::vector<Point_2>& points) const {
{
std::vector<Direction_2> directions; std::vector<Direction_2> directions;
std::size_t n = points.size(); std::size_t n = points.size();
for (std::size_t i = 0; i < n-1; ++i) for (std::size_t i = 0; i < n-1; ++i) {
{
directions.push_back(f_direction(f_vector(points[i], points[i+1]))); directions.push_back(f_direction(f_vector(points[i], points[i+1])));
} }
directions.push_back(f_direction(f_vector(points[n-1], points[0]))); directions.push_back(f_direction(f_vector(points[n-1], points[0])));
@ -362,69 +333,59 @@ private:
return directions; return directions;
} }
/*! \brief determines whether three vertices on the outer CCB of a face are
* locally convex.
*/
bool is_convex(const Point_2& prev, const Point_2& curr, bool is_convex(const Point_2& prev, const Point_2& curr,
const Point_2& next) const const Point_2& next) const
{ { return f_orientation(prev, curr, next) == LEFT_TURN; }
return f_orientation(prev, curr, next) == LEFT_TURN;
}
// Returns the point corresponding to a state (i,j). //! \brief obtains the point corresponding to a state (i,j).
Point_2 get_point(int i1, int i2, const std::vector<Point_2>& pgn1, Point_2 get_point(int i1, int i2, const std::vector<Point_2>& pgn1,
const std::vector<Point_2>& pgn2) const const std::vector<Point_2>& pgn2) const
{ { return f_add(pgn1[i1], Vector_2(Point_2(ORIGIN), pgn2[i2])); }
return f_add(pgn1[i1], Vector_2(Point_2(ORIGIN), pgn2[i2])); //! \brief puts the outer loop of the arrangement in 'outer_boundary'
} void get_outer_loop(const Arrangement_history_2& arr,
Polygon_2& outer_boundary) const {
Inner_ccb_const_iterator icit = arr.unbounded_face()->inner_ccbs_begin();
Ccb_halfedge_const_circulator circ_start = *icit;
Ccb_halfedge_const_circulator circ = circ_start;
// Put the outer loop of the arrangement in 'outer_boundary' do outer_boundary.push_back(circ->source()->point());
void get_outer_loop(Arrangement_history_2& arr,
Polygon_2& outer_boundary) const
{
Inner_ccb_iterator icit = arr.unbounded_face()->inner_ccbs_begin();
Ccb_halfedge_circulator circ_start = *icit;
Ccb_halfedge_circulator circ = circ_start;
do
{
outer_boundary.push_back(circ->source()->point());
}
while (--circ != circ_start); while (--circ != circ_start);
} }
// Determine whether the face orientation is consistent. //! \brief determines whether the face orientation is consistent.
bool test_face_orientation(const Arrangement_history_2& arr, bool test_face_orientation(const Arrangement_history_2& arr,
const Face_handle face) const const Face_const_handle face) const {
{
// The face needs to be orientable // The face needs to be orientable
Ccb_halfedge_circulator start = face->outer_ccb(); Ccb_halfedge_const_circulator start = face->outer_ccb();
Ccb_halfedge_circulator circ = start; Ccb_halfedge_const_circulator circ = start;
do if (!do_original_edges_have_same_direction(arr, circ)) return false; do if (!do_original_edges_have_same_direction(arr, circ)) return false;
while (++circ != start); while (++circ != start);
return true; return true;
} }
// Add a face to 'holes'. //! \brief adds a face to 'holes'.
template <typename OutputIterator> template <typename OutputIterator>
void add_face(const Face_handle face, OutputIterator holes) const void add_face(Face_const_handle face, OutputIterator holes) const {
{
Polygon_2 pgn_hole; Polygon_2 pgn_hole;
Ccb_halfedge_circulator start = face->outer_ccb(); Ccb_halfedge_const_circulator start = face->outer_ccb();
Ccb_halfedge_circulator circ = start; Ccb_halfedge_const_circulator circ = start;
do pgn_hole.push_back(circ->source()->point()); do pgn_hole.push_back(circ->source()->point());
while (--circ != start); while (--circ != start);
*holes = pgn_hole; *holes = pgn_hole;
++holes; ++holes;
} }
// Check whether the convolution's original edge(s) had the same direction as /*! \brief checks whether the convolution's original edge(s) had the same
// the arrangement's half edge * direction as the arrangement's half edge.
*/
bool do_original_edges_have_same_direction(const Arrangement_history_2& arr, bool do_original_edges_have_same_direction(const Arrangement_history_2& arr,
const Halfedge_handle he) const Halfedge_const_handle he) const {
{ for (auto segment_itr = arr.originating_curves_begin(he);
Originating_curve_iterator segment_itr;
for (segment_itr = arr.originating_curves_begin(he);
segment_itr != arr.originating_curves_end(he); ++segment_itr) segment_itr != arr.originating_curves_end(he); ++segment_itr)
{ {
if (f_compare_xy(segment_itr->source(), segment_itr->target()) == if (f_compare_xy(segment_itr->source(), segment_itr->target()) ==
@ -437,41 +398,34 @@ private:
return true; return true;
} }
// Return a point in the face's interior by finding a diagonal //! \brief obtains a point in the face's interior by finding a diagonal
Point_2 get_point_in_face(const Face_handle face) const Point_2 get_point_in_face(Face_const_handle face) const {
{ Ccb_halfedge_const_circulator next = face->outer_ccb();
Ccb_halfedge_circulator current_edge = face->outer_ccb(); Ccb_halfedge_const_circulator curr = next++;
Ccb_halfedge_circulator next_edge = current_edge;
next_edge++;
Point_2 a, v, b; // Move over the face's vertices until a convex corner is encountered.
// Observe that the outer ccb of a hole is clockwise oriented.
// Move over the face's vertices until a convex corner is encountered: while (! is_convex(curr->source()->point(),
do curr->target()->point(),
{ next->target()->point())) {
a = current_edge->source()->point(); curr = next;
v = current_edge->target()->point(); ++next;
b = next_edge->target()->point();
current_edge++;
next_edge++;
} }
while (!is_convex(a, v, b));
const auto& a = curr->source()->point();
const auto& v = curr->target()->point();
const auto& b = next->target()->point();
Triangle_2 ear(a, v, b); Triangle_2 ear(a, v, b);
FT min_distance = -1; FT min_distance = -1;
const Point_2* min_q = 0; const Point_2* min_q = nullptr;
// Of the remaining vertices, find the one inside of the "ear" with minimal // Of the remaining vertices, find the one inside of the "ear" with minimal
// distance to v: // distance to v:
while (++next_edge != current_edge) while (++next != curr) {
{ const Point_2& q = next->target()->point();
const Point_2& q = next_edge->target()->point(); if (ear.has_on_bounded_side(q)) {
if (ear.has_on_bounded_side(q))
{
FT distance = squared_distance(q, v); FT distance = squared_distance(q, v);
if ((min_q == 0) || (distance < min_distance)) if ((min_q == 0) || (distance < min_distance)) {
{
min_distance = distance; min_distance = distance;
min_q = &q; min_q = &q;
} }
@ -483,15 +437,14 @@ private:
return (min_q == 0) ? centroid(ear) : midpoint(v, *min_q); return (min_q == 0) ? centroid(ear) : midpoint(v, *min_q);
} }
//! \brief transforms a polygon with holes.
template <typename Transformation> template <typename Transformation>
Polygon_with_holes_2 transform(const Transformation& t, Polygon_with_holes_2 transform(const Transformation& t,
const Polygon_with_holes_2& p) const const Polygon_with_holes_2& p) const {
{
Polygon_with_holes_2 result(CGAL::transform(t, p.outer_boundary())); Polygon_with_holes_2 result(CGAL::transform(t, p.outer_boundary()));
typename Polygon_with_holes_2::Hole_const_iterator it = p.holes_begin(); auto it = p.holes_begin();
while (it != p.holes_end()) while (it != p.holes_end()) {
{
Polygon_2 p2(it->vertices_begin(), it->vertices_end()); Polygon_2 p2(it->vertices_begin(), it->vertices_end());
result.add_hole(CGAL::transform(t, p2)); result.add_hole(CGAL::transform(t, p2));
++it; ++it;

View File

@ -23,6 +23,7 @@
#include <CGAL/Nef_S2/Normalizing.h> #include <CGAL/Nef_S2/Normalizing.h>
#include <CGAL/Unique_hash_map.h> #include <CGAL/Unique_hash_map.h>
#include <CGAL/Nef_3/SNC_decorator.h> #include <CGAL/Nef_3/SNC_decorator.h>
#include <CGAL/Nef_3/SNC_const_decorator.h>
#include <CGAL/Nef_S2/SM_decorator.h> #include <CGAL/Nef_S2/SM_decorator.h>
#include <CGAL/Nef_S2/SM_point_locator.h> #include <CGAL/Nef_S2/SM_point_locator.h>
#include <CGAL/Nef_3/SNC_SM_overlayer.h> #include <CGAL/Nef_3/SNC_SM_overlayer.h>
@ -74,6 +75,7 @@ class Binary_operation : public CGAL::SNC_decorator<Map> {
typedef typename SNC_structure::Items Items; typedef typename SNC_structure::Items Items;
typedef typename Map::Sphere_map Sphere_map; typedef typename Map::Sphere_map Sphere_map;
typedef CGAL::SNC_decorator<SNC_structure> SNC_decorator; typedef CGAL::SNC_decorator<SNC_structure> SNC_decorator;
typedef CGAL::SNC_const_decorator<SNC_structure> SNC_const_decorator;
typedef SNC_decorator Base; typedef SNC_decorator Base;
typedef CGAL::SNC_constructor<Items, SNC_structure> SNC_constructor; typedef CGAL::SNC_constructor<Items, SNC_structure> SNC_constructor;
typedef CGAL::SNC_external_structure<Items, SNC_structure> typedef CGAL::SNC_external_structure<Items, SNC_structure>
@ -82,10 +84,13 @@ class Binary_operation : public CGAL::SNC_decorator<Map> {
typedef CGAL::SNC_SM_overlayer<Items, SM_decorator> SM_overlayer; typedef CGAL::SNC_SM_overlayer<Items, SM_decorator> SM_overlayer;
typedef CGAL::SM_point_locator<SM_decorator> SM_point_locator; typedef CGAL::SM_point_locator<SM_decorator> SM_point_locator;
typedef CGAL::SNC_point_locator<SNC_decorator> SNC_point_locator; typedef CGAL::SNC_point_locator<SNC_decorator> SNC_point_locator;
typedef CGAL::SNC_point_locator<SNC_const_decorator> SNC_const_point_locator;
typedef typename SNC_structure::Vertex_handle Vertex_handle; typedef typename SNC_structure::Vertex_handle Vertex_handle;
typedef typename SNC_structure::Halfedge_handle Halfedge_handle; typedef typename SNC_structure::Halfedge_handle Halfedge_handle;
typedef typename SNC_structure::Halfedge_const_handle Halfedge_const_handle;
typedef typename SNC_structure::Halffacet_handle Halffacet_handle; typedef typename SNC_structure::Halffacet_handle Halffacet_handle;
typedef typename SNC_structure::Halffacet_const_handle Halffacet_const_handle;
typedef typename SNC_structure::Volume_handle Volume_handle; typedef typename SNC_structure::Volume_handle Volume_handle;
typedef typename SNC_structure::SVertex_handle SVertex_handle; typedef typename SNC_structure::SVertex_handle SVertex_handle;
typedef typename SNC_structure::SHalfedge_handle SHalfedge_handle; typedef typename SNC_structure::SHalfedge_handle SHalfedge_handle;
@ -144,12 +149,12 @@ class Binary_operation : public CGAL::SNC_decorator<Map> {
return v01; return v01;
} }
Vertex_handle create_local_view_on( const Point_3& p, Halfedge_handle e) { Vertex_handle create_local_view_on( const Point_3& p, Halfedge_const_handle e) {
SNC_constructor C(*this->sncp()); SNC_constructor C(*this->sncp());
return C.create_from_edge( e, p); return C.create_from_edge( e, p);
} }
Vertex_handle create_local_view_on( const Point_3& p, Halffacet_handle f) { Vertex_handle create_local_view_on( const Point_3& p, Halffacet_const_handle f) {
SNC_constructor C(*this->sncp()); SNC_constructor C(*this->sncp());
return C.create_from_facet( f, p); return C.create_from_facet( f, p);
} }
@ -167,14 +172,14 @@ class Binary_operation : public CGAL::SNC_decorator<Map> {
typename Selection, typename Selection,
typename Association> typename Association>
class Intersection_call_back : class Intersection_call_back :
public SNC_point_locator::Intersection_call_back public SNC_const_point_locator::Intersection_call_back
{ {
typedef typename SNC_decorator::Decorator_traits Decorator_traits; typedef typename SNC_decorator::Decorator_traits Decorator_traits;
typedef typename Decorator_traits::Halfedge_handle Halfedge_handle; typedef typename Decorator_traits::Halfedge_handle Halfedge_handle;
typedef typename Decorator_traits::Halffacet_handle Halffacet_handle; typedef typename Decorator_traits::Halffacet_handle Halffacet_handle;
public: public:
Intersection_call_back( SNC_structure& s0, SNC_structure& s1, Intersection_call_back( const SNC_structure& s0, const SNC_structure& s1,
const Selection& _bop, SNC_structure& r, const Selection& _bop, SNC_structure& r,
bool invert_order, Association& Ain) : bool invert_order, Association& Ain) :
snc0(s0), snc1(s1), bop(_bop), result(r), snc0(s0), snc1(s1), bop(_bop), result(r),
@ -456,12 +461,10 @@ class Binary_operation : public CGAL::SNC_decorator<Map> {
// CGAL_NEF_SETDTHREAD(19*509*43*131); // CGAL_NEF_SETDTHREAD(19*509*43*131);
Intersection_call_back<SNC_decorator, Selection, Association> call_back0 Intersection_call_back<SNC_const_decorator, Selection, Association> call_back0
( const_cast<SNC_structure&>(snc1), const_cast<SNC_structure&>(snc2), ( snc1, snc2, BOP, *this->sncp(), false, A);
BOP, *this->sncp(), false, A); Intersection_call_back<SNC_const_decorator, Selection, Association> call_back1
Intersection_call_back<SNC_decorator, Selection, Association> call_back1 ( snc2, snc2, BOP, *this->sncp(), true, A);
( const_cast<SNC_structure&>(snc2), const_cast<SNC_structure&>(snc2),
BOP, *this->sncp(), true, A);
#ifdef CGAL_NEF3_TIMER_INTERSECTION #ifdef CGAL_NEF3_TIMER_INTERSECTION
double split_intersection = timer_overlay.time(); double split_intersection = timer_overlay.time();
@ -503,10 +506,8 @@ class Binary_operation : public CGAL::SNC_decorator<Map> {
<< this->sncp()->number_of_vertices()); << this->sncp()->number_of_vertices());
#else #else
CGAL_NEF_TRACEN("intersection by fast box intersection"); CGAL_NEF_TRACEN("intersection by fast box intersection");
binop_intersection_test_segment_tree<SNC_decorator> binop_box_intersection; binop_intersection_test_segment_tree<SNC_const_decorator> binop_box_intersection;
binop_box_intersection(call_back0, call_back1, binop_box_intersection(call_back0, call_back1, snc1, snc2);
const_cast<SNC_structure&>(snc1),
const_cast<SNC_structure&>(snc2));
#endif #endif
#ifdef CGAL_NEF3_TIMER_INTERSECTION #ifdef CGAL_NEF3_TIMER_INTERSECTION

Some files were not shown because too many files have changed in this diff Show More