Merge branch 'master' into Kinetic_shape_reconstruction-new_package-soesau

This commit is contained in:
Sven Oesau 2023-01-29 15:25:18 +01:00 committed by GitHub
commit 4717cf3727
117 changed files with 1404 additions and 901 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

@ -3,6 +3,7 @@ name: Documentation
on: on:
issue_comment: issue_comment:
types: [created] types: [created]
workflow_dispatch:
permissions: permissions:
contents: read # to fetch code (actions/checkout) contents: read # to fetch code (actions/checkout)
@ -74,7 +75,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

@ -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

@ -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

@ -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

@ -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,7 +26,7 @@ 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 Python3_EXECUTABLE) if (NOT Python3_EXECUTABLE)
@ -138,6 +138,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

@ -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

@ -555,87 +555,32 @@ MainWindow::loadWKT(QString filename)
{ {
//Polygons todo : make it multipolygons //Polygons todo : make it multipolygons
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

@ -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

@ -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

@ -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

@ -690,7 +690,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

@ -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

@ -5,7 +5,6 @@ EXTRACT_ALL = false
HIDE_UNDOC_CLASSES = true HIDE_UNDOC_CLASSES = true
WARN_IF_UNDOCUMENTED = true WARN_IF_UNDOCUMENTED = true
EXCLUDE = ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Optimal_bounding_box/internal
EXCLUDE_SYMBOLS += experimental EXCLUDE_SYMBOLS += experimental
HTML_EXTRA_FILES = ${CGAL_PACKAGE_DOC_DIR}/fig/aabb_vs_obb.jpg \ HTML_EXTRA_FILES = ${CGAL_PACKAGE_DOC_DIR}/fig/aabb_vs_obb.jpg \

View File

@ -172,9 +172,9 @@ void R_s_k_2::draw_edge_footpoints(const Triangulation& mesh,
Sample_vector::const_iterator it; Sample_vector::const_iterator it;
for (it = samples.begin(); it != samples.end(); ++it) for (it = samples.begin(); it != samples.end(); ++it)
{ {
Sample_* sample = *it; const Sample_& sample = this->m_samples[* it];
Point p = sample->point(); Point p = sample.point();
FT m = 0.5*(1.0 - sample->mass()); FT m = 0.5*(1.0 - sample.mass());
Point q; Point q;
if (mesh.get_plan(edge) == 0) if (mesh.get_plan(edge) == 0)
@ -188,7 +188,7 @@ void R_s_k_2::draw_edge_footpoints(const Triangulation& mesh,
else else
{ {
viewer->glColor3f(red + m, green + m, blue + m); viewer->glColor3f(red + m, green + m, blue + m);
FT t = sample->coordinate(); FT t = sample.coordinate();
q = CGAL::ORIGIN + (1.0 - t)*(a - CGAL::ORIGIN) + t*(b - CGAL::ORIGIN); q = CGAL::ORIGIN + (1.0 - t)*(a - CGAL::ORIGIN) + t*(b - CGAL::ORIGIN);
} }
draw_segment(p, q); draw_segment(p, q);
@ -395,8 +395,8 @@ void R_s_k_2::draw_bins_plan0(const Edge& edge)
Sample_vector_const_iterator it; Sample_vector_const_iterator it;
for (it = samples.begin(); it != samples.end(); ++it) for (it = samples.begin(); it != samples.end(); ++it)
{ {
Sample_* sample = *it; const Sample_& sample = this->m_samples[* it];
const Point& ps = sample->point(); const Point& ps = sample.point();
Point q = pa; Point q = pa;
FT Da = CGAL::squared_distance(ps, pa); FT Da = CGAL::squared_distance(ps, pa);
@ -422,8 +422,8 @@ void R_s_k_2::draw_bins_plan1(const Edge& edge)
PSample psample = queue.top(); PSample psample = queue.top();
queue.pop(); queue.pop();
const FT m = psample.sample()->mass(); const FT m = this->m_samples[psample.sample()].mass();
const Point& ps = psample.sample()->point(); const Point& ps = this->m_samples[psample.sample()].point();
FT bin = m/M; FT bin = m/M;
FT alpha = start + 0.5*bin; FT alpha = start + 0.5*bin;
@ -510,7 +510,7 @@ void R_s_k_2::draw_one_ring(const float point_size, const float line_width, cons
bool ok = locate_edge(query, edge); bool ok = locate_edge(query, edge);
if (!ok) return; if (!ok) return;
Triangulation copy; Triangulation copy(this->m_samples);
Edge copy_edge = copy_star(edge, copy); Edge copy_edge = copy_star(edge, copy);
draw_mesh_one_ring(point_size, line_width, copy, copy_edge); draw_mesh_one_ring(point_size, line_width, copy, copy_edge);
} }
@ -549,7 +549,7 @@ void R_s_k_2::draw_blocking_edges(const float point_size, const float line_width
bool ok = locate_edge(query, edge); bool ok = locate_edge(query, edge);
if (!ok) return; if (!ok) return;
Triangulation copy; Triangulation copy(this->m_samples);
Edge copy_edge = copy_star(edge, copy); Edge copy_edge = copy_star(edge, copy);
draw_mesh_blocking_edges(point_size, line_width, copy, copy_edge); draw_mesh_blocking_edges(point_size, line_width, copy, copy_edge);
} }
@ -589,7 +589,7 @@ void R_s_k_2::draw_collapsible_edge(const float point_size,
bool ok = locate_edge(query, edge); bool ok = locate_edge(query, edge);
if (!ok) return; if (!ok) return;
Triangulation copy; Triangulation copy(this->m_samples);
Edge copy_edge = copy_star(edge, copy); Edge copy_edge = copy_star(edge, copy);
Vertex_handle copy_src = copy.source_vertex(copy_edge); Vertex_handle copy_src = copy.source_vertex(copy_edge);
@ -611,7 +611,7 @@ void R_s_k_2::draw_cost_stencil(const float point_size,
bool ok = locate_edge(query, edge); bool ok = locate_edge(query, edge);
if (!ok) return; if (!ok) return;
Triangulation copy; Triangulation copy(this->m_samples);
Edge copy_edge = copy_star(edge, copy); Edge copy_edge = copy_star(edge, copy);
Vertex_handle copy_src = copy.source_vertex(copy_edge); Vertex_handle copy_src = copy.source_vertex(copy_edge);
@ -708,7 +708,7 @@ void R_s_k_2::draw_push_queue_stencil(const float point_size,
it++; it++;
} }
Triangulation copy; Triangulation copy(this->m_samples);
Edge_vector copy_hull; Edge_vector copy_hull;
Edge_vector copy_stencil; Edge_vector copy_stencil;
Edge copy_edge = copy_star(edge, copy); Edge copy_edge = copy_star(edge, copy);

View File

@ -74,8 +74,8 @@ public:
typedef R_s_2::Edge_vector Edge_vector; typedef R_s_2::Edge_vector Edge_vector;
typedef R_s_2::Sample_ Sample_; typedef R_s_2::Sample_ Sample_;
typedef R_s_2::Sample_vector Sample_vector; typedef std::vector<Sample_> Sample_vector;
typedef R_s_2::Sample_vector_const_iterator Sample_vector_const_iterator; typedef Sample_vector::const_iterator Sample_vector_const_iterator;
typedef R_s_2::PSample PSample; typedef R_s_2::PSample PSample;
typedef R_s_2::SQueue SQueue; typedef R_s_2::SQueue SQueue;
@ -452,7 +452,7 @@ public:
for (std::vector<Sample_>::iterator it = m_samples.begin(); for (std::vector<Sample_>::iterator it = m_samples.begin();
it != m_samples.end(); ++it) { it != m_samples.end(); ++it) {
Sample_& s = *it; Sample_& s = *it;
samples.push_back(&s); samples.push_back(s);
} }
if (filename.contains(".xy", Qt::CaseInsensitive)) { if (filename.contains(".xy", Qt::CaseInsensitive)) {
@ -469,8 +469,8 @@ public:
std::ofstream ofs(qPrintable(filename)); std::ofstream ofs(qPrintable(filename));
for (Sample_vector_const_iterator it = samples.begin(); for (Sample_vector_const_iterator it = samples.begin();
it != samples.end(); ++it) { it != samples.end(); ++it) {
Sample_* sample = *it; const Sample_& sample = *it;
ofs << sample->point() << std::endl; ofs << sample.point() << std::endl;
} }
ofs.close(); ofs.close();
} }
@ -505,12 +505,12 @@ public:
Sample_vector_const_iterator it; Sample_vector_const_iterator it;
for (it = vertices.begin(); it != vertices.end(); it++) { for (it = vertices.begin(); it != vertices.end(); it++) {
vertices_mass_list.push_back( vertices_mass_list.push_back(
std::make_pair((*it)->point(), (*it)->mass())); std::make_pair((*it).point(), (*it).mass()));
} }
PointMassList samples_mass_list; PointMassList samples_mass_list;
for (it = samples.begin(); it != samples.end(); it++) { for (it = samples.begin(); it != samples.end(); it++) {
samples_mass_list.push_back( samples_mass_list.push_back(
std::make_pair((*it)->point(), (*it)->mass())); std::make_pair((*it).point(), (*it).mass()));
} }
Point_property_map point_pmap; Point_property_map point_pmap;
@ -551,10 +551,10 @@ public:
for (it = m_samples.begin(); it != m_samples.end(); ++it) { for (it = m_samples.begin(); it != m_samples.end(); ++it) {
Sample_& s = *it; Sample_& s = *it;
samples.push_back(&s); samples.push_back(s);
FT rv = random.get_double(0.0, 1.0); FT rv = random.get_double(0.0, 1.0);
if (rv <= percentage) if (rv <= percentage)
vertices.push_back(&s); vertices.push_back(s);
} }
} }

View File

@ -16,6 +16,7 @@ typedef CGAL::Optimal_transportation_reconstruction_2<K> Otr;
int main () int main ()
{ {
CGAL::get_default_random() = CGAL::Random(1671586136);
// Generate a set of random points on the boundary of a square. // Generate a set of random points on the boundary of a square.
std::vector<Point> points; std::vector<Point> points;
CGAL::Random_points_on_square_2<Point> point_generator(1.); CGAL::Random_points_on_square_2<Point> point_generator(1.);

View File

@ -50,13 +50,13 @@ public:
const FT total_weight() const { return m_total_weight; } const FT total_weight() const { return m_total_weight; }
template <typename SampleContainer> template <typename Samples, typename SampleContainer>
void set_total_weight(const SampleContainer& samples) void set_total_weight(const Samples& m_samples, const SampleContainer& samples)
{ {
m_total_weight = (FT)0; m_total_weight = (FT)0;
for (typename SampleContainer::const_iterator it = samples.begin(); for (typename SampleContainer::const_iterator it = samples.begin();
it != samples.end(); ++ it) it != samples.end(); ++ it)
m_total_weight += (*it)->mass(); m_total_weight += m_samples[*it].mass();
} }
FT finalize(const FT alpha = FT(0.5)) const FT finalize(const FT alpha = FT(0.5)) const

View File

@ -16,7 +16,6 @@
#include <CGAL/OTR_2/Cost.h> #include <CGAL/OTR_2/Cost.h>
#include <CGAL/OTR_2/Sample.h>
#include <CGAL/Triangulation_face_base_2.h> #include <CGAL/Triangulation_face_base_2.h>
#include <vector> #include <vector>
@ -51,7 +50,7 @@ public:
typedef typename Traits_::FT FT; typedef typename Traits_::FT FT;
typedef OTR_2::Cost<FT> Cost_; typedef OTR_2::Cost<FT> Cost_;
typedef OTR_2::Sample<Traits_> Sample_; typedef OTR_2::Sample<Traits_> Sample_;
typedef std::vector<Sample_*> Sample_vector; typedef std::vector<int> Sample_vector;
private: private:
Sample_vector m_samples[3]; Sample_vector m_samples[3];
@ -176,7 +175,7 @@ public:
const Sample_vector& samples(int edge) const { return m_samples[edge]; } const Sample_vector& samples(int edge) const { return m_samples[edge]; }
Sample_vector& samples(int edge) { return m_samples[edge]; } Sample_vector& samples(int edge) { return m_samples[edge]; }
void add_sample(int edge, Sample_* sample) void add_sample(int edge, int sample)
{ {
m_samples[edge].push_back(sample); m_samples[edge].push_back(sample);
} }

View File

@ -110,7 +110,7 @@ public:
typedef OTR_2::Cost<FT> Cost_; typedef OTR_2::Cost<FT> Cost_;
typedef OTR_2::Sample<Traits_> Sample_; typedef OTR_2::Sample<Traits_> Sample_;
typedef std::vector<Sample_*> Sample_vector; typedef std::vector<int> Sample_vector;
typedef typename Sample_vector::const_iterator Sample_vector_const_iterator; typedef typename Sample_vector::const_iterator Sample_vector_const_iterator;
typedef OTR_2::Sample_with_priority<Sample_> PSample; typedef OTR_2::Sample_with_priority<Sample_> PSample;
@ -135,12 +135,13 @@ public:
> >
> MultiIndex; > MultiIndex;
std::vector<Sample_>& m_samples;
FT m_factor; // ghost vs solid FT m_factor; // ghost vs solid
mutable Random rng; mutable Random rng;
public: public:
Reconstruction_triangulation_2(Traits_ traits = Traits_()) Reconstruction_triangulation_2(std::vector<Sample_>& samples, Traits_ traits = Traits_())
: Base(traits), m_factor(1.) : Base(traits), m_samples(samples), m_factor(1.)
{ {
} }
@ -360,11 +361,11 @@ public:
if (cleanup) if (cleanup)
face->clean_all_samples(); face->clean_all_samples();
} }
Sample_* sample = vertex->sample(); int sample = vertex->sample();
if (sample) if (sample != -1)
samples.push_back(sample); samples.push_back(sample);
if (cleanup) if (cleanup)
vertex->set_sample(nullptr); vertex->set_sample(-1);
} }
void collect_all_samples(Sample_vector& samples) const { void collect_all_samples(Sample_vector& samples) const {
@ -391,7 +392,7 @@ public:
} }
for (Finite_vertices_iterator vi = Base::finite_vertices_begin(); for (Finite_vertices_iterator vi = Base::finite_vertices_begin();
vi != Base::finite_vertices_end(); ++vi) { vi != Base::finite_vertices_end(); ++vi) {
vi->set_sample(nullptr); vi->set_sample(-1);
} }
} }
@ -465,15 +466,15 @@ public:
typename Sample_vector::const_iterator it; typename Sample_vector::const_iterator it;
const Sample_vector& samples0 = edge.first->samples(edge.second); const Sample_vector& samples0 = edge.first->samples(edge.second);
for (it = samples0.begin(); it != samples0.end(); ++it) { for (it = samples0.begin(); it != samples0.end(); ++it) {
Sample_* sample = *it; const Sample_ & sample = m_samples[* it];
mass += sample->mass(); mass += sample.mass();
} }
Edge twin = twin_edge(edge); Edge twin = twin_edge(edge);
const Sample_vector& samples1 = twin.first->samples(twin.second); const Sample_vector& samples1 = twin.first->samples(twin.second);
for (it = samples1.begin(); it != samples1.end(); ++it) { for (it = samples1.begin(); it != samples1.end(); ++it) {
Sample_* sample = *it; const Sample_& sample = m_samples[* it];
mass += sample->mass(); mass += sample.mass();
} }
set_mass(edge, mass); set_mass(edge, mass);
@ -511,15 +512,15 @@ public:
typename Sample_vector::const_iterator it; typename Sample_vector::const_iterator it;
const Sample_vector& samples0 = edge.first->samples(edge.second); const Sample_vector& samples0 = edge.first->samples(edge.second);
for (it = samples0.begin(); it != samples0.end(); ++it) { for (it = samples0.begin(); it != samples0.end(); ++it) {
Sample_* sample = *it; const Sample_& sample = m_samples[* it];
squeue.push(PSample(sample, sample->coordinate())); squeue.push(PSample(*it, sample.coordinate()));
} }
Edge twin = twin_edge(edge); Edge twin = twin_edge(edge);
const Sample_vector& samples1 = twin.first->samples(twin.second); const Sample_vector& samples1 = twin.first->samples(twin.second);
for (it = samples1.begin(); it != samples1.end(); ++it) { for (it = samples1.begin(); it != samples1.end(); ++it) {
Sample_* sample = *it; const Sample_& sample = m_samples[* it];
squeue.push(PSample(sample, 1.0 - sample->coordinate())); squeue.push(PSample(*it, 1.0 - sample.coordinate()));
} }
} }
@ -537,13 +538,13 @@ public:
PSample psample = squeue.top(); PSample psample = squeue.top();
squeue.pop(); squeue.pop();
FT mass = psample.sample()->mass(); FT mass = m_samples[psample.sample()].mass();
FT coord = psample.priority() * L; FT coord = psample.priority() * L;
FT bin = mass * coef; FT bin = mass * coef;
FT center = start + FT(0.5) * bin; FT center = start + FT(0.5) * bin;
FT pos = coord - center; FT pos = coord - center;
FT norm2 = psample.sample()->distance2(); FT norm2 = m_samples[psample.sample()].distance2();
FT tang2 = bin * bin / 12 + pos * pos; FT tang2 = bin * bin / 12 + pos * pos;
sum.add(Cost_(norm2, tang2), mass); sum.add(Cost_(norm2, tang2), mass);
@ -566,15 +567,15 @@ public:
Cost_ sum; Cost_ sum;
for (Sample_vector_const_iterator it = samples.begin(); for (Sample_vector_const_iterator it = samples.begin();
it != samples.end(); ++it) { it != samples.end(); ++it) {
Sample_* sample = *it; const Sample_& sample = m_samples[* it];
FT mass = sample->mass(); FT mass = sample.mass();
const Point& query = sample->point(); const Point& query = sample.point();
FT Ds = geom_traits().compute_squared_distance_2_object()(query, ps); FT Ds = geom_traits().compute_squared_distance_2_object()(query, ps);
FT Dt = geom_traits().compute_squared_distance_2_object()(query, pt); FT Dt = geom_traits().compute_squared_distance_2_object()(query, pt);
FT dist2 = ((std::min))(Ds, Dt); FT dist2 = ((std::min))(Ds, Dt);
FT norm2 = sample->distance2(); FT norm2 = sample.distance2();
FT tang2 = dist2 - norm2; FT tang2 = dist2 - norm2;
sum.add(Cost_(norm2, tang2), mass); sum.add(Cost_(norm2, tang2), mass);
@ -589,7 +590,7 @@ public:
template<class Iterator> // value_type = Sample_* template<class Iterator> // value_type = Sample_*
void assign_samples(Iterator begin, Iterator end) { void assign_samples(Iterator begin, Iterator end) {
for (Iterator it = begin; it != end; ++it) { for (Iterator it = begin; it != end; ++it) {
Sample_* sample = *it; int sample = *it;
assign_sample(sample); assign_sample(sample);
} }
} }
@ -597,13 +598,13 @@ public:
template<class Iterator> // value_type = Sample_* template<class Iterator> // value_type = Sample_*
void assign_samples_brute_force(Iterator begin, Iterator end) { void assign_samples_brute_force(Iterator begin, Iterator end) {
for (Iterator it = begin; it != end; ++it) { for (Iterator it = begin; it != end; ++it) {
Sample_* sample = *it; int sample = *it;
assign_sample_brute_force(sample); assign_sample_brute_force(sample);
} }
} }
bool assign_sample(Sample_* sample) { bool assign_sample(int sample) {
const Point& point = sample->point(); const Point& point = m_samples[sample].point();
Face_handle face = Base::locate(point); Face_handle face = Base::locate(point);
if (face == Face_handle() || Base::is_infinite(face)) { if (face == Face_handle() || Base::is_infinite(face)) {
@ -622,8 +623,9 @@ public:
return true; return true;
} }
bool assign_sample_brute_force(Sample_* sample) { bool assign_sample_brute_force(int sample_index) {
const Point& point = sample->point(); const Sample_& sample = m_samples[sample_index];
const Point& point = sample.point();
Face_handle nearest_face = Face_handle(); Face_handle nearest_face = Face_handle();
for (Finite_faces_iterator fi = Base::finite_faces_begin(); for (Finite_faces_iterator fi = Base::finite_faces_begin();
fi != Base::finite_faces_end(); ++fi) { fi != Base::finite_faces_end(); ++fi) {
@ -641,12 +643,12 @@ public:
Vertex_handle vertex = find_nearest_vertex(point, nearest_face); Vertex_handle vertex = find_nearest_vertex(point, nearest_face);
if (vertex != Vertex_handle()) { if (vertex != Vertex_handle()) {
assign_sample_to_vertex(sample, vertex); assign_sample_to_vertex(sample_index, vertex);
return true; return true;
} }
Edge edge = find_nearest_edge(point, nearest_face); Edge edge = find_nearest_edge(point, nearest_face);
assign_sample_to_edge(sample, edge); assign_sample_to_edge(sample_index, edge);
return true; return true;
} }
@ -688,23 +690,24 @@ public:
return nearest; return nearest;
} }
void assign_sample_to_vertex(Sample_* sample, Vertex_handle vertex) const { void assign_sample_to_vertex(int sample_index, Vertex_handle vertex) const {
/*if (vertex->sample()) { /*if (vertex->sample()) {
std::cout << "assign to vertex: vertex already has sample" std::cout << "assign to vertex: vertex already has sample"
<< std::endl; << std::endl;
}*/ }*/
Sample_& sample = m_samples[sample_index];
sample->distance2() = FT(0); sample.distance2() = FT(0);
sample->coordinate() = FT(0); sample.coordinate() = FT(0);
vertex->set_sample(sample); vertex->set_sample(sample_index);
} }
void assign_sample_to_edge(Sample_* sample, const Edge& edge) const { void assign_sample_to_edge(int sample_index, const Edge& edge) const {
Sample_& sample = m_samples[sample_index];
Segment segment = get_segment(edge); Segment segment = get_segment(edge);
const Point& query = sample->point(); const Point& query = sample.point();
sample->distance2() = compute_distance2(query, segment); sample.distance2() = compute_distance2(query, segment);
sample->coordinate() = compute_coordinate(query, segment); sample.coordinate() = compute_coordinate(query, segment);
edge.first->add_sample(edge.second, sample); edge.first->add_sample(edge.second, sample_index);
} }
FT compute_distance2(const Point& query, const Segment& segment) const { FT compute_distance2(const Point& query, const Segment& segment) const {

View File

@ -50,7 +50,7 @@ public:
private: private:
int m_id; int m_id;
bool m_pinned; bool m_pinned;
Sample_* m_sample; int m_sample;
Point m_relocated; Point m_relocated;
FT m_relevance; FT m_relevance;
@ -60,7 +60,7 @@ public:
: Base(), : Base(),
m_id(-1), m_id(-1),
m_pinned(false), m_pinned(false),
m_sample(nullptr), m_sample(-1),
m_relevance(0) m_relevance(0)
{ {
} }
@ -69,7 +69,7 @@ public:
: Base(p), : Base(p),
m_id(-1), m_id(-1),
m_pinned(false), m_pinned(false),
m_sample(nullptr), m_sample(-1),
m_relevance(0) m_relevance(0)
{ {
} }
@ -78,7 +78,7 @@ public:
: Base(f), : Base(f),
m_id(-1), m_id(-1),
m_pinned(false), m_pinned(false),
m_sample(nullptr), m_sample(-1),
m_relevance(0) m_relevance(0)
{ {
} }
@ -87,7 +87,7 @@ public:
: Base(p, f), : Base(p, f),
m_id(-1), m_id(-1),
m_pinned(false), m_pinned(false),
m_sample(nullptr), m_sample(-1),
m_relevance(0) m_relevance(0)
{ {
} }
@ -103,13 +103,13 @@ public:
FT relevance() const { return m_relevance; } FT relevance() const { return m_relevance; }
void set_relevance(FT relevance) { m_relevance = relevance; } void set_relevance(FT relevance) { m_relevance = relevance; }
Sample_* sample() const { return m_sample; } int sample() const { return m_sample; }
void set_sample(Sample_* sample) { m_sample = sample; } void set_sample(int sample) { m_sample = sample; }
const Point& relocated() const { return m_relocated; } const Point& relocated() const { return m_relocated; }
Point& relocated() { return m_relocated; } Point& relocated() { return m_relocated; }
bool has_sample_assigned() const { return sample() != nullptr; } bool has_sample_assigned() const { return sample() != -1; }
}; };
//---------------STRUCT LESS VERTEX_HANDLE--------------------- //---------------STRUCT LESS VERTEX_HANDLE---------------------
template <class T> template <class T>

View File

@ -39,6 +39,9 @@ private:
FT m_backup_coord; FT m_backup_coord;
public: public:
Sample()
{}
Sample(const Point& point, Sample(const Point& point,
const FT mass = FT(1)) const FT mass = FT(1))
: m_point(point), : m_point(point),
@ -94,23 +97,20 @@ public:
typedef typename Sample_::FT FT; typedef typename Sample_::FT FT;
private: private:
Sample_* m_sample; int m_sample;
FT m_priority; FT m_priority;
public: public:
Sample_with_priority(Sample_* sample, const FT priority = FT(0)) Sample_with_priority(int sample, const FT priority = FT(0))
{ : m_sample(sample), m_priority(priority)
m_sample = sample; {}
m_priority = priority;
}
Sample_with_priority(const Sample_with_priority& psample) Sample_with_priority(const Sample_with_priority& psample)
{ : m_sample(psample.sample()), m_priority(psample.priority())
m_sample = psample.sample(); {}
m_priority = psample.priority();
}
~Sample_with_priority() { } ~Sample_with_priority()
{}
Sample_with_priority& operator = (const Sample_with_priority& psample) Sample_with_priority& operator = (const Sample_with_priority& psample)
{ {
@ -119,7 +119,7 @@ public:
return *this; return *this;
} }
Sample_* sample() const { return m_sample; } int sample() const { return m_sample; }
const FT priority() const { return m_priority; } const FT priority() const { return m_priority; }
}; };

View File

@ -117,7 +117,6 @@ public:
The Output simplex. The Output simplex.
*/ */
typedef OTR_2::Reconstruction_triangulation_2<Traits> Triangulation; typedef OTR_2::Reconstruction_triangulation_2<Traits> Triangulation;
typedef typename Triangulation::Vertex Vertex; typedef typename Triangulation::Vertex Vertex;
typedef typename Triangulation::Vertex_handle Vertex_handle; typedef typename Triangulation::Vertex_handle Vertex_handle;
typedef typename Triangulation::Vertex_iterator Vertex_iterator; typedef typename Triangulation::Vertex_iterator Vertex_iterator;
@ -159,6 +158,7 @@ public:
/// @} /// @}
protected: protected:
std::vector<Sample_> m_samples;
Triangulation m_dt; Triangulation m_dt;
Traits const& m_traits; Traits const& m_traits;
MultiIndex m_mindex; MultiIndex m_mindex;
@ -175,7 +175,6 @@ protected:
MassPMap mass_pmap; MassPMap mass_pmap;
public: public:
/// \name Initialization /// \name Initialization
/// @{ /// @{
@ -212,7 +211,8 @@ public:
unsigned int relocation = 2, unsigned int relocation = 2,
int verbose = 0, int verbose = 0,
Traits traits = Traits()) Traits traits = Traits())
: m_dt(traits), : m_samples(),
m_dt(m_samples, traits),
m_traits(m_dt.geom_traits()), m_traits(m_dt.geom_traits()),
m_ignore(0), m_ignore(0),
m_verbose(verbose), m_verbose(verbose),
@ -318,8 +318,9 @@ public:
/// \cond SKIP_IN_MANUAL /// \cond SKIP_IN_MANUAL
Optimal_transportation_reconstruction_2() Optimal_transportation_reconstruction_2()
: m_traits(m_dt.geom_traits()) : m_samples(), m_dt(m_samples), m_traits(m_dt.geom_traits())
{ {
initialize_parameters(); initialize_parameters();
} }
@ -369,14 +370,18 @@ public:
insert_loose_bbox(bbox); insert_loose_bbox(bbox);
init(start, beyond); init(start, beyond);
std::vector<Sample_*> m_samples; m_samples.reserve(std::distance(start,beyond));
for (InputIterator it = start; it != beyond; it++) { for (InputIterator it = start; it != beyond; it++) {
Point point = get(point_pmap, *it); Point point = get(point_pmap, *it);
FT mass = get( mass_pmap, *it); FT mass = get( mass_pmap, *it);
Sample_* s = new Sample_(point, mass); Sample_ s(point, mass);
m_samples.push_back(s); m_samples.push_back(s);
} }
assign_samples(m_samples.begin(), m_samples.end()); Sample_vector sv(m_samples.size());
for(int i = 0; i < static_cast<int>(sv.size()); ++i){
sv[i] = i;
}
assign_samples(sv.begin(), sv.end());
} }
template <class InputIterator> template <class InputIterator>
@ -398,7 +403,7 @@ public:
insert_loose_bbox(bbox); insert_loose_bbox(bbox);
init(vertices_start, vertices_beyond); init(vertices_start, vertices_beyond);
std::vector<Sample_*> m_samples; m_samples.reserve(std::distance(samples_start, samples_beyond));
for (InputIterator it = samples_start; it != samples_beyond; it++) { for (InputIterator it = samples_start; it != samples_beyond; it++) {
#ifdef CGAL_USE_PROPERTY_MAPS_API_V1 #ifdef CGAL_USE_PROPERTY_MAPS_API_V1
Point point = get(point_pmap, it); Point point = get(point_pmap, it);
@ -407,10 +412,14 @@ public:
Point point = get(point_pmap, *it); Point point = get(point_pmap, *it);
FT mass = get( mass_pmap, *it); FT mass = get( mass_pmap, *it);
#endif #endif
Sample_* s = new Sample_(point, mass); Sample_ s(point, mass);
m_samples.push_back(s); m_samples.push_back(s);
} }
assign_samples(m_samples.begin(), m_samples.end()); Sample_vector sv(m_samples.size());
for(int i = 0; i < static_cast<int>(sv.size()); ++i){
sv[i] = i;
}
assign_samples(sv.begin(), sv.end());
} }
@ -422,16 +431,8 @@ public:
return m_traits.construct_vector_2_object()(dx, dy); return m_traits.construct_vector_2_object()(dx, dy);
} }
void clear() { void clear()
Sample_vector samples; {}
m_dt.collect_all_samples(samples);
// Deallocate samples
for (Sample_vector_const_iterator s_it = samples.begin();
s_it != samples.end(); ++s_it)
{
delete *s_it;
}
}
// INIT // // INIT //
@ -494,7 +495,7 @@ public:
m_dt.cleanup_assignments(); m_dt.cleanup_assignments();
} }
template<class Iterator> // value_type = Sample_* template<class Iterator> // value_type = int
void assign_samples(Iterator begin, Iterator end) { void assign_samples(Iterator begin, Iterator end) {
CGAL::Real_timer timer; CGAL::Real_timer timer;
if (m_verbose > 0) if (m_verbose > 0)
@ -587,7 +588,7 @@ public:
<< s->id() << "->" << t->id() << ") ... " << std::endl; << s->id() << "->" << t->id() << ") ... " << std::endl;
} }
Triangulation copy; Triangulation copy(m_samples);
Edge copy_edge = copy_star(edge, copy); Edge copy_edge = copy_star(edge, copy);
Vertex_handle copy_source = copy.source_vertex(copy_edge); Vertex_handle copy_source = copy.source_vertex(copy_edge);
@ -632,7 +633,7 @@ public:
copy.assign_samples_brute_force(samples.begin(), samples.end()); copy.assign_samples_brute_force(samples.begin(), samples.end());
copy.reset_all_costs(); copy.reset_all_costs();
cost = copy.compute_total_cost(); cost = copy.compute_total_cost();
cost.set_total_weight (samples); cost.set_total_weight (m_samples, samples);
restore_samples(samples.begin(), samples.end()); restore_samples(samples.begin(), samples.end());
if (m_verbose > 1) { if (m_verbose > 1) {
@ -643,18 +644,18 @@ public:
} }
template<class Iterator> // value_type = Sample_* template<class Iterator> // value_type = Sample_*
void backup_samples(Iterator begin, Iterator end) const { void backup_samples(Iterator begin, Iterator end) {
for (Iterator it = begin; it != end; ++it) { for (Iterator it = begin; it != end; ++it) {
Sample_* sample = *it; Sample_& sample = m_samples[* it];
sample->backup(); sample.backup();
} }
} }
template<class Iterator> // value_type = Sample_* template<class Iterator> // value_type = Sample_*
void restore_samples(Iterator begin, Iterator end) const { void restore_samples(Iterator begin, Iterator end) {
for (Iterator it = begin; it != end; ++it) { for (Iterator it = begin; it != end; ++it) {
Sample_* sample = *it; Sample_& sample = m_samples[* it];
sample->restore(); sample.restore();
} }
} }
@ -1089,7 +1090,7 @@ public:
m_dt.collect_samples_from_edge(twin, samples); m_dt.collect_samples_from_edge(twin, samples);
copy_twin.first->samples(copy_twin.second) = samples; copy_twin.first->samples(copy_twin.second) = samples;
} }
copy_vertex->set_sample(nullptr); copy_vertex->set_sample(-1);
} }
Edge get_copy_edge( Edge get_copy_edge(
@ -1230,10 +1231,10 @@ public:
void compute_relocation_for_vertex( void compute_relocation_for_vertex(
Vertex_handle vertex, FT& coef, Vector& rhs) const Vertex_handle vertex, FT& coef, Vector& rhs) const
{ {
Sample_* sample = vertex->sample(); if (vertex->sample() != -1) {
if (sample) { const Sample_& sample = m_samples[vertex->sample()];
const FT m = sample->mass(); const FT m = sample.mass();
const Point& ps = sample->point(); const Point& ps = sample.point();
rhs = m_traits.construct_sum_of_vectors_2_object()(rhs, rhs = m_traits.construct_sum_of_vectors_2_object()(rhs,
m_traits.construct_scaled_vector_2_object()( m_traits.construct_scaled_vector_2_object()(
m_traits.construct_vector_2_object()(CGAL::ORIGIN, ps), m)); m_traits.construct_vector_2_object()(CGAL::ORIGIN, ps), m));
@ -1253,9 +1254,9 @@ public:
Vector grad = m_traits.construct_vector_2_object()(FT(0), FT(0)); Vector grad = m_traits.construct_vector_2_object()(FT(0), FT(0));
Sample_vector_const_iterator it; Sample_vector_const_iterator it;
for (it = samples.begin(); it != samples.end(); ++it) { for (it = samples.begin(); it != samples.end(); ++it) {
Sample_* sample = *it; const Sample_& sample = m_samples[* it];
const FT m = sample->mass(); const FT m = sample.mass();
const Point& ps = sample->point(); const Point& ps = sample.point();
FT Da = m_traits.compute_squared_distance_2_object()(ps, pa); FT Da = m_traits.compute_squared_distance_2_object()(ps, pa);
FT Db = m_traits.compute_squared_distance_2_object()(ps, pb); FT Db = m_traits.compute_squared_distance_2_object()(ps, pb);
@ -1281,9 +1282,9 @@ public:
Sample_vector_const_iterator it; Sample_vector_const_iterator it;
for (it = samples.begin(); it != samples.end(); ++it) { for (it = samples.begin(); it != samples.end(); ++it) {
Sample_* sample = *it; const Sample_& sample = m_samples[* it];
const FT m = sample->mass(); const FT m = sample.mass();
const Point& ps = sample->point(); const Point& ps = sample.point();
FT Da = m_traits.compute_squared_distance_2_object()(ps, pa); FT Da = m_traits.compute_squared_distance_2_object()(ps, pa);
FT Db = m_traits.compute_squared_distance_2_object()(ps, pb); FT Db = m_traits.compute_squared_distance_2_object()(ps, pb);
@ -1311,8 +1312,8 @@ public:
PSample psample = queue.top(); PSample psample = queue.top();
queue.pop(); queue.pop();
const FT m = psample.sample()->mass(); const FT m = this->m_samples[psample.sample()].mass();
const Point& ps = psample.sample()->point(); const Point& ps = this->m_samples[psample.sample()].point();
// normal + tangnetial // normal + tangnetial
const FT coord = psample.priority(); const FT coord = psample.priority();
@ -1357,8 +1358,8 @@ public:
PSample psample = queue.top(); PSample psample = queue.top();
queue.pop(); queue.pop();
const FT m = psample.sample()->mass(); const FT m = m_samples[psample.sample()].mass();
const Point& ps = psample.sample()->point(); const Point& ps = m_samples[psample.sample()].point();
const FT coord = psample.priority(); const FT coord = psample.priority();
const FT one_minus_coord = 1.0 - coord; const FT one_minus_coord = 1.0 - coord;

View File

@ -37,8 +37,14 @@ int main ()
std::back_inserter(isolated_points), std::back_inserter(edges)); std::back_inserter(isolated_points), std::back_inserter(edges));
std::cout << "Isolated_points: " << isolated_points.size() << std::endl; std::cout << "Isolated_points: " << isolated_points.size() << std::endl;
std::cout << "Edges: " << edges.size() << std::endl; for(Point p : isolated_points){
std::cout << p << std::endl;
}
std::cout << "Edges: " << edges.size() << std::endl;
for(Segment s : edges){
std::cout << s << std::endl;
}
assert(isolated_points.size() == 0); assert(isolated_points.size() == 0);
assert(edges.size() == 8); assert(edges.size() == 8);
} }

View File

@ -56,7 +56,6 @@ void test(std::size_t dataset_size) {
// Count the jumps in depth // Count the jumps in depth
auto jumps = count_jumps(octree); auto jumps = count_jumps(octree);
std::cout << "un-graded octree has " << jumps << " jumps" << std::endl; std::cout << "un-graded octree has " << jumps << " jumps" << std::endl;
assert(jumps > 0);
// Grade the octree // Grade the octree
octree.grade(); octree.grade();

View File

@ -16,7 +16,6 @@ ALIASES += "cgalDescribePolylineType=A polyline is defined as a sequence of poin
EXAMPLE_PATH += ${CGAL_Poisson_surface_reconstruction_3_EXAMPLE_DIR} EXAMPLE_PATH += ${CGAL_Poisson_surface_reconstruction_3_EXAMPLE_DIR}
EXCLUDE = ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Polygon_mesh_processing/internal
EXCLUDE_SYMBOLS += experimental EXCLUDE_SYMBOLS += experimental
HTML_EXTRA_FILES = ${CGAL_PACKAGE_DOC_DIR}/fig/selfintersections.jpg \ HTML_EXTRA_FILES = ${CGAL_PACKAGE_DOC_DIR}/fig/selfintersections.jpg \

View File

@ -616,7 +616,12 @@ compute_vertex_normal_as_sum_of_weighted_normals(typename boost::graph_traits<Po
/** /**
* \ingroup PMP_normal_grp * \ingroup PMP_normal_grp
* *
* computes the unit normal at vertex `v` as the average of the normals of incident faces. * \brief computes the unit normal at vertex `v` as a function of the normals of incident faces.
*
* The implementation is inspired by Aubry et al. "On the most 'normal' normal" \cgalCite{cgal:al-otmnn-08},
* which aims to compute a normal that maximises the visibility to the incident faces.
* If such normal does not exist or if the optimization process fails to find it, a fallback normal is computed
* as a sine-weighted sum of the normals of the incident faces.
* *
* @note The function `compute_vertex_normals()` should be preferred if normals are intended to be * @note The function `compute_vertex_normals()` should be preferred if normals are intended to be
* computed at all vertices of the graph. * computed at all vertices of the graph.

View File

@ -1393,12 +1393,15 @@ public:
} }
} }
if (inconsistent_classification()) return; if (inconsistent_classification()) return;
if (!used_to_clip_a_surface && !used_to_classify_patches)
{
CGAL_assertion( patch_status_was_not_already_set[0] || previous_bitvalue[0]==is_patch_inside_tm2[patch_id_p1] ); CGAL_assertion( patch_status_was_not_already_set[0] || previous_bitvalue[0]==is_patch_inside_tm2[patch_id_p1] );
CGAL_assertion( patch_status_was_not_already_set[1] || previous_bitvalue[1]==is_patch_inside_tm2[patch_id_p2] ); CGAL_assertion( patch_status_was_not_already_set[1] || previous_bitvalue[1]==is_patch_inside_tm2[patch_id_p2] );
CGAL_assertion( patch_status_was_not_already_set[2] || previous_bitvalue[2]==is_patch_inside_tm1[patch_id_q1] ); CGAL_assertion( patch_status_was_not_already_set[2] || previous_bitvalue[2]==is_patch_inside_tm1[patch_id_q1] );
CGAL_assertion( patch_status_was_not_already_set[3] || previous_bitvalue[3]==is_patch_inside_tm1[patch_id_q2] ); CGAL_assertion( patch_status_was_not_already_set[3] || previous_bitvalue[3]==is_patch_inside_tm1[patch_id_q2] );
} }
} }
}
if (used_to_classify_patches) if (used_to_classify_patches)
{ {

View File

@ -1941,6 +1941,7 @@ remove_self_intersections_one_step(std::set<typename boost::graph_traits<Triangl
const bool treat_all_CCs, const bool treat_all_CCs,
const double strong_dihedral_angle, const double strong_dihedral_angle,
const double weak_dihedral_angle, const double weak_dihedral_angle,
const bool use_smoothing,
const double containment_epsilon, const double containment_epsilon,
const Projector& projector, const Projector& projector,
VertexPointMap vpm, VertexPointMap vpm,
@ -2185,7 +2186,7 @@ remove_self_intersections_one_step(std::set<typename boost::graph_traits<Triangl
// //
// Do not smooth if there are no self-intersections within the patch: this means the intersection // Do not smooth if there are no self-intersections within the patch: this means the intersection
// is with another CC and smoothing is unlikely to move the surface sufficiently // is with another CC and smoothing is unlikely to move the surface sufficiently
if(self_intersects) if(use_smoothing && self_intersects)
{ {
bool fixed_by_smoothing = false; bool fixed_by_smoothing = false;
@ -2390,6 +2391,8 @@ bool remove_self_intersections(const FaceRange& face_range,
// detect_feature_pp NP (unused for now) // detect_feature_pp NP (unused for now)
const double weak_dihedral_angle = 0.; // choose_parameter(get_parameter(np, internal_np::weak_dihedral_angle), 20.); const double weak_dihedral_angle = 0.; // choose_parameter(get_parameter(np, internal_np::weak_dihedral_angle), 20.);
const bool use_smoothing = choose_parameter(get_parameter(np, internal_np::use_smoothing), false);
struct Return_false struct Return_false
{ {
bool operator()(std::pair<face_descriptor, face_descriptor>) const { return false; } bool operator()(std::pair<face_descriptor, face_descriptor>) const { return false; }
@ -2488,7 +2491,7 @@ bool remove_self_intersections(const FaceRange& face_range,
internal::remove_self_intersections_one_step( internal::remove_self_intersections_one_step(
faces_to_treat, working_face_range, tmesh, step, faces_to_treat, working_face_range, tmesh, step,
preserve_genus, treat_all_CCs, strong_dihedral_angle, weak_dihedral_angle, preserve_genus, treat_all_CCs, strong_dihedral_angle, weak_dihedral_angle,
containment_epsilon, projector, vpm, gt, visitor); use_smoothing, containment_epsilon, projector, vpm, gt, visitor);
#ifdef CGAL_PMP_REMOVE_SELF_INTERSECTION_DEBUG #ifdef CGAL_PMP_REMOVE_SELF_INTERSECTION_DEBUG
if(all_fixed && topology_issue) if(all_fixed && topology_issue)

View File

@ -1032,7 +1032,7 @@ private:
bool bool
is_two_facets_neighbouring(const unsigned int & pid, const unsigned int &i, const unsigned int &j)const is_two_facets_neighboring(const unsigned int & pid, const unsigned int &i, const unsigned int &j)const
{ {
std::size_t facesize = halfspace[pid].size(); std::size_t facesize = halfspace[pid].size();
if (i == j) return false; if (i == j) return false;
@ -1046,6 +1046,9 @@ private:
if (j == 2 && i == facesize - 1) return true; if (j == 2 && i == facesize - 1) return true;
return false; return false;
} }
CGAL_DEPRECATED bool
is_two_facets_neighbouring(const unsigned int & pid, const unsigned int &i, const unsigned int &j)const
{ return is_two_facets_neighboring(pid, i, j); }
int int
@ -1187,7 +1190,7 @@ private:
continue; continue;
if (true /* USE_ADJACENT_INFORMATION*/ ) { if (true /* USE_ADJACENT_INFORMATION*/ ) {
bool neib = is_two_facets_neighbouring(cindex, cutp[i], cutp[j]); bool neib = is_two_facets_neighboring(cindex, cutp[i], cutp[j]);
if (neib == false) continue; if (neib == false) continue;
} }
@ -1295,7 +1298,7 @@ private:
const int &prismid, const unsigned int &faceid)const const int &prismid, const unsigned int &faceid)const
{ {
for (unsigned int i = 0; i < halfspace[prismid].size(); i++) { for (unsigned int i = 0; i < halfspace[prismid].size(); i++) {
/*bool neib = is_two_facets_neighbouring(prismid, i, faceid);// this works only when the polyhedron is convex and no two neighbor facets are coplanar /*bool neib = is_two_facets_neighboring(prismid, i, faceid);// this works only when the polyhedron is convex and no two neighbor facets are coplanar
if (neib == false) continue;*/ if (neib == false) continue;*/
if (i == faceid) continue; if (i == faceid) continue;
if(oriented_side(halfspace[prismid][i].eplane, ip) == ON_POSITIVE_SIDE){ if(oriented_side(halfspace[prismid][i].eplane, ip) == ON_POSITIVE_SIDE){
@ -1722,11 +1725,11 @@ private:
idlist.emplace_back(filtered_intersection[queue[0]]);// idlist contains the id in prismid//it is fine maybe it is not really intersected idlist.emplace_back(filtered_intersection[queue[0]]);// idlist contains the id in prismid//it is fine maybe it is not really intersected
coverlist[queue[0]] = 1 ;//when filtered_intersection[i] is already in the cover list, coverlist[i]=true coverlist[queue[0]] = 1 ;//when filtered_intersection[i] is already in the cover list, coverlist[i]=true
std::vector<unsigned int> neighbours;//local id std::vector<unsigned int> neighbors;//local id
std::vector<unsigned int > list; std::vector<unsigned int > list;
std::vector<std::vector<unsigned int>*> neighbour_facets; std::vector<std::vector<unsigned int>*> neighbor_facets;
std::vector<std::vector<unsigned int>> idlistorder; std::vector<std::vector<unsigned int>> idlistorder;
std::vector<int> neighbour_cover; std::vector<int> neighbor_cover;
idlistorder.emplace_back(intersect_face[queue[0]]); idlistorder.emplace_back(intersect_face[queue[0]]);
for (unsigned int i = 0; i < queue.size(); i++) { for (unsigned int i = 0; i < queue.size(); i++) {
@ -1810,14 +1813,14 @@ private:
localtree.all_intersected_primitives(bounding_boxes[jump1], std::back_inserter(list)); localtree.all_intersected_primitives(bounding_boxes[jump1], std::back_inserter(list));
neighbours.resize(list.size()); neighbors.resize(list.size());
neighbour_facets.resize(list.size()); neighbor_facets.resize(list.size());
neighbour_cover.resize(list.size()); neighbor_cover.resize(list.size());
for (unsigned int j = 0; j < list.size(); j++) { for (unsigned int j = 0; j < list.size(); j++) {
neighbours[j] = filtered_intersection[list[j]]; neighbors[j] = filtered_intersection[list[j]];
neighbour_facets[j] = &(intersect_face[list[j]]); neighbor_facets[j] = &(intersect_face[list[j]]);
if (coverlist[list[j]] == 1) neighbour_cover[j] = 1; if (coverlist[list[j]] == 1) neighbor_cover[j] = 1;
else neighbour_cover[j] = 0; else neighbor_cover[j] = 0;
} }
for (unsigned int j = 0; j < i; j++) { for (unsigned int j = 0; j < i; j++) {
@ -1864,7 +1867,7 @@ private:
if (inter == 1) { if (inter == 1) {
inter = Implicit_Tri_Facet_Facet_interpoint_Out_Prism_return_local_id_with_face_order_jump_over(ip, neighbours, neighbour_facets, neighbour_cover, jump1, jump2, check_id); inter = Implicit_Tri_Facet_Facet_interpoint_Out_Prism_return_local_id_with_face_order_jump_over(ip, neighbors, neighbor_facets, neighbor_cover, jump1, jump2, check_id);
if (inter == 1) { if (inter == 1) {

View File

@ -99,7 +99,10 @@ void test(const Mesh& mesh,
if(CGAL::is_triangle(halfedge(f, mesh), mesh)) if(CGAL::is_triangle(halfedge(f, mesh), mesh))
{ {
if (PMP::is_degenerate_triangle_face(f, mesh)) if (PMP::is_degenerate_triangle_face(f, mesh))
{
if (std::is_same<K, EPECK>())
assert(get(fnormals, f) == CGAL::NULL_VECTOR); assert(get(fnormals, f) == CGAL::NULL_VECTOR);
}
else else
assert(get(fnormals, f) != CGAL::NULL_VECTOR); assert(get(fnormals, f) != CGAL::NULL_VECTOR);
} }

View File

@ -173,8 +173,10 @@ void test_constructions(const G& g,
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
bar = PMP::barycentric_coordinates(p, q, r, p, K()); bar = PMP::barycentric_coordinates(p, q, r, p, K());
assert(is_equal(bar[0], FT(1)) && is_equal(bar[1], FT(0)) && is_equal(bar[2], FT(0))); assert(is_equal(bar[0], FT(1)) && is_equal(bar[1], FT(0)) && is_equal(bar[2], FT(0)));
bar = PMP::barycentric_coordinates(p, q, r, q, K()); bar = PMP::barycentric_coordinates(p, q, r, q, K());
assert(is_equal(bar[0], FT(0)) && is_equal(bar[1], FT(1)) && is_equal(bar[2], FT(0))); assert(is_equal(bar[0], FT(0)) && is_equal(bar[1], FT(1)) && is_equal(bar[2], FT(0)));
bar = PMP::barycentric_coordinates(p, q, r, r, K()); bar = PMP::barycentric_coordinates(p, q, r, r, K());
assert(is_equal(bar[0], FT(0)) && is_equal(bar[1], FT(0)) && is_equal(bar[2], FT(1))); assert(is_equal(bar[0], FT(0)) && is_equal(bar[1], FT(0)) && is_equal(bar[2], FT(1)));
@ -217,6 +219,7 @@ void test_constructions(const G& g,
loc = std::make_pair(f, CGAL::make_array(FT(1), FT(0), FT(0))); loc = std::make_pair(f, CGAL::make_array(FT(1), FT(0), FT(0)));
assert(PMP::is_on_vertex(loc, source(halfedge(f, g), g), g)); assert(PMP::is_on_vertex(loc, source(halfedge(f, g), g), g));
dv = PMP::get_descriptor_from_location(loc, g); dv = PMP::get_descriptor_from_location(loc, g);
if(const vertex_descriptor* v = boost::get<vertex_descriptor>(&dv)) { } else { assert(false); } if(const vertex_descriptor* v = boost::get<vertex_descriptor>(&dv)) { } else { assert(false); }
@ -266,6 +269,7 @@ void test_random_entities(const G& g, CGAL::Random& rnd)
loc.second[1] >= FT(0) && loc.second[1] <= FT(1) && loc.second[1] >= FT(0) && loc.second[1] <= FT(1) &&
loc.second[2] >= FT(0) && loc.second[2] <= FT(1)); loc.second[2] >= FT(0) && loc.second[2] <= FT(1));
int h_id = CGAL::halfedge_index_in_face(h, g); int h_id = CGAL::halfedge_index_in_face(h, g);
assert(loc.second[(h_id + 2) % 3] == FT(0)); assert(loc.second[(h_id + 2) % 3] == FT(0));
} }
} }
@ -432,6 +436,7 @@ void test_locate_in_face(const G& g,
Point_reference p = get(vpm, v); Point_reference p = get(vpm, v);
loc = PMP::locate_vertex<FT>(v, g); loc = PMP::locate_vertex<FT>(v, g);
assert(is_equal(loc.second[CGAL::vertex_index_in_face(v, loc.first, g)], FT(1))); assert(is_equal(loc.second[CGAL::vertex_index_in_face(v, loc.first, g)], FT(1)));
assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g) + 1) % 3], FT(0))); assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g) + 1) % 3], FT(0)));
assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g) + 2) % 3], FT(0))); assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g) + 2) % 3], FT(0)));
@ -475,10 +480,11 @@ void test_locate_in_face(const G& g,
neigh_loc.second[(neigh_hd_id+2)%3] = FT(0); neigh_loc.second[(neigh_hd_id+2)%3] = FT(0);
PMP::locate_in_adjacent_face(loc, neigh_f, g); PMP::locate_in_adjacent_face(loc, neigh_f, g);
assert(PMP::locate_in_common_face<FT>(loc, neigh_loc, g)); assert(PMP::locate_in_common_face<FT>(loc, neigh_loc, g));
if (std::is_same<K, EPECK>()) {
assert(PMP::locate_in_common_face<FT>(loc, p, neigh_loc, g, CGAL::parameters::vertex_point_map(vpm).geom_traits(K()))); assert(PMP::locate_in_common_face<FT>(loc, p, neigh_loc, g, CGAL::parameters::vertex_point_map(vpm).geom_traits(K())));
}
assert(PMP::locate_in_common_face<FT>(loc, p, neigh_loc, g, CGAL::parameters::vertex_point_map(vpm).geom_traits(K()), 1e-7)); assert(PMP::locate_in_common_face<FT>(loc, p, neigh_loc, g, CGAL::parameters::vertex_point_map(vpm).geom_traits(K()), 1e-7));
} }
} }
@ -536,8 +542,7 @@ struct Locate_with_AABB_tree_Tester // 2D case
// sanitize otherwise some test platforms fail // sanitize otherwise some test platforms fail
PMP::internal::snap_location_to_border(loc, g, FT(1e-7)); PMP::internal::snap_location_to_border(loc, g, FT(1e-7));
assert(PMP::is_on_vertex(loc, v, g)); // might fail due to precision issues...
assert(PMP::is_on_vertex(loc, v, g)); // might fail du to precision issues...
assert(is_equal(loc.second[CGAL::vertex_index_in_face(v, loc.first, g)], FT(1))); assert(is_equal(loc.second[CGAL::vertex_index_in_face(v, loc.first, g)], FT(1)));
assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g) + 1) % 3], FT(0))); assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g) + 1) % 3], FT(0)));
assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g) + 2) % 3], FT(0))); assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g) + 2) % 3], FT(0)));
@ -552,18 +557,25 @@ struct Locate_with_AABB_tree_Tester // 2D case
loc = PMP::locate(p_a, g, CGAL::parameters::vertex_point_map(vpm)); loc = PMP::locate(p_a, g, CGAL::parameters::vertex_point_map(vpm));
assert(is_equal(CGAL::squared_distance(to_p3( assert(is_equal(CGAL::squared_distance(to_p3(
PMP::construct_point(loc, g, CGAL::parameters::vertex_point_map(vpm))), p3_a), FT(0))); PMP::construct_point(loc, g, CGAL::parameters::vertex_point_map(vpm))), p3_a), FT(0)));
if (std::is_same<K, EPECK>()) {
assert(PMP::is_in_face(loc, g)); assert(PMP::is_in_face(loc, g));
}
loc = PMP::locate_with_AABB_tree(CGAL::ORIGIN, tree_b, g, CGAL::parameters::vertex_point_map(vpm_b)); loc = PMP::locate_with_AABB_tree(CGAL::ORIGIN, tree_b, g, CGAL::parameters::vertex_point_map(vpm_b));
if (std::is_same<K, EPECK>()) {
assert(PMP::is_in_face(loc, g)); assert(PMP::is_in_face(loc, g));
}
loc = PMP::locate(CGAL::ORIGIN, g, CGAL::parameters::vertex_point_map(vpm_b)); loc = PMP::locate(CGAL::ORIGIN, g, CGAL::parameters::vertex_point_map(vpm_b));
if (std::is_same<K, EPECK>()) {
assert(PMP::is_in_face(loc, g)); assert(PMP::is_in_face(loc, g));
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
Ray_2 r2 = random_2D_ray<CGAL::AABB_tree<AABB_face_graph_traits> >(tree_a, rnd); Ray_2 r2 = random_2D_ray<CGAL::AABB_tree<AABB_face_graph_traits> >(tree_a, rnd);
loc = PMP::locate_with_AABB_tree(r2, tree_a, g, CGAL::parameters::vertex_point_map(vpm)); loc = PMP::locate_with_AABB_tree(r2, tree_a, g, CGAL::parameters::vertex_point_map(vpm));
if(loc.first != boost::graph_traits<G>::null_face()) if(loc.first != boost::graph_traits<G>::null_face() && std::is_same<K, EPECK>())
assert(PMP::is_in_face(loc, g)); assert(PMP::is_in_face(loc, g));
Ray_3 r3 = random_3D_ray<CGAL::AABB_tree<AABB_face_graph_traits> >(tree_b, rnd); Ray_3 r3 = random_3D_ray<CGAL::AABB_tree<AABB_face_graph_traits> >(tree_b, rnd);
@ -654,25 +666,35 @@ struct Locate_with_AABB_tree_Tester<K, VPM, 3> // 3D
assert(tree_b.size() == num_faces(g)); assert(tree_b.size() == num_faces(g));
Face_location loc = PMP::locate_with_AABB_tree(p3_a, tree_a, g, CGAL::parameters::vertex_point_map(vpm)); Face_location loc = PMP::locate_with_AABB_tree(p3_a, tree_a, g, CGAL::parameters::vertex_point_map(vpm));
if (std::is_same<K, EPECK>()) {
assert(is_equal(loc.second[CGAL::vertex_index_in_face(v, loc.first, g)], FT(1))); assert(is_equal(loc.second[CGAL::vertex_index_in_face(v, loc.first, g)], FT(1)));
assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g) + 1) % 3], FT(0))); assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g) + 1) % 3], FT(0)));
assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g) + 2) % 3], FT(0))); assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g) + 2) % 3], FT(0)));
assert(is_equal(CGAL::squared_distance(PMP::construct_point(loc, g), p3_a), FT(0))); assert(is_equal(CGAL::squared_distance(PMP::construct_point(loc, g), p3_a), FT(0)));
}
loc = PMP::locate_with_AABB_tree(p3_a, tree_a, g, CGAL::parameters::vertex_point_map(vpm)); loc = PMP::locate_with_AABB_tree(p3_a, tree_a, g, CGAL::parameters::vertex_point_map(vpm));
if (std::is_same<K, EPECK>()) {
assert(is_equal(CGAL::squared_distance(PMP::construct_point(loc, g), p3_a), FT(0))); assert(is_equal(CGAL::squared_distance(PMP::construct_point(loc, g), p3_a), FT(0)));
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
loc = PMP::locate(p3_a, g, CGAL::parameters::snapping_tolerance(1e-7)); loc = PMP::locate(p3_a, g, CGAL::parameters::snapping_tolerance(1e-7));
if (std::is_same<K, EPECK>()) {
assert(is_equal(CGAL::squared_distance(PMP::construct_point(loc, g), p3_a), FT(0))); assert(is_equal(CGAL::squared_distance(PMP::construct_point(loc, g), p3_a), FT(0)));
assert(PMP::is_in_face(loc, g)); assert(PMP::is_in_face(loc, g));
}
loc = PMP::locate_with_AABB_tree(CGAL::ORIGIN, tree_b, g, CGAL::parameters::vertex_point_map(custom_vpm_3D)); loc = PMP::locate_with_AABB_tree(CGAL::ORIGIN, tree_b, g, CGAL::parameters::vertex_point_map(custom_vpm_3D));
if (std::is_same<K, EPECK>()) {
assert(PMP::is_in_face(loc, g)); assert(PMP::is_in_face(loc, g));
}
// Doesn't necessarily have to wrap with a P_to_P3: it can be done automatically internally // Doesn't necessarily have to wrap with a P_to_P3: it can be done automatically internally
loc = PMP::locate(CGAL::ORIGIN, g, CGAL::parameters::vertex_point_map(custom_vpm)); loc = PMP::locate(CGAL::ORIGIN, g, CGAL::parameters::vertex_point_map(custom_vpm));
if (std::is_same<K, EPECK>()) {
assert(PMP::is_in_face(loc, g)); assert(PMP::is_in_face(loc, g));
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
Ray_3 r3 = random_3D_ray<CGAL::AABB_tree<AABB_face_graph_traits_with_WVPM> >(tree_b, rnd); Ray_3 r3 = random_3D_ray<CGAL::AABB_tree<AABB_face_graph_traits_with_WVPM> >(tree_b, rnd);
@ -848,7 +870,7 @@ void test(CGAL::Random& rnd)
{ {
test_2D_triangulation<K>("data/stair.xy", rnd); test_2D_triangulation<K>("data/stair.xy", rnd);
// test_2D_surface_mesh<K>("data/blobby_2D.off", rnd); // temporarily disabled, until Surface_mesh's IO is "fixed" // test_2D_surface_mesh<K>("data/blobby_2D.off", rnd); // temporarily disabled, until Surface_mesh's IO is "fixed"
test_surface_mesh_3D<K>(CGAL::data_file_path("meshes/mech-holes-shark.off"), rnd); test_surface_mesh_3D<K>("meshes/mech-holes-shark.off", rnd);
test_surface_mesh_projection<K>("data/unit-grid.off", rnd); test_surface_mesh_projection<K>("data/unit-grid.off", rnd);
test_polyhedron<K>("data-coref/elephant_split_2.off", rnd); test_polyhedron<K>("data-coref/elephant_split_2.off", rnd);
} }

View File

@ -1,3 +1,2 @@
@INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS} @INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS}
PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - Polygonal Surface Reconstruction" PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - Polygonal Surface Reconstruction"
EXCLUDE = ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Polygonal_surface_reconstruction/internal

View File

@ -1337,6 +1337,7 @@ bool Io_image_plugin::loadDirectory(const QString& dirname,
QApplication::restoreOverrideCursor(); QApplication::restoreOverrideCursor();
CGAL::Three::Three::warning("VTK is required to read DCM and BMP files"); CGAL::Three::Three::warning("VTK is required to read DCM and BMP files");
CGAL_USE(dirname); CGAL_USE(dirname);
CGAL_USE(ext);
return false; return false;
#else #else
QFileInfo fileinfo; QFileInfo fileinfo;
@ -1440,6 +1441,7 @@ Image* Io_image_plugin::createDirectoryImage(const QString& dirname,
CGAL::Three::Three::warning("VTK is required to read DCM and BMP files"); CGAL::Three::Three::warning("VTK is required to read DCM and BMP files");
CGAL_USE(dirname); CGAL_USE(dirname);
CGAL_USE(ext); CGAL_USE(ext);
CGAL_USE(smooth);
#else #else
auto create_image = [&](auto&& reader) -> void auto create_image = [&](auto&& reader) -> void
{ {

View File

@ -50,7 +50,6 @@ void compute_angles(Mesh* poly,Tester tester , double& mini, double& maxi, doubl
typedef typename boost::graph_traits<Mesh>::face_descriptor face_descriptor; typedef typename boost::graph_traits<Mesh>::face_descriptor face_descriptor;
typedef typename boost::property_map<Mesh, CGAL::vertex_point_t>::type VPMap; typedef typename boost::property_map<Mesh, CGAL::vertex_point_t>::type VPMap;
typedef typename CGAL::Kernel_traits< typename boost::property_traits<VPMap>::value_type >::Kernel Traits; typedef typename CGAL::Kernel_traits< typename boost::property_traits<VPMap>::value_type >::Kernel Traits;
double rad_to_deg = 180. / CGAL_PI;
accumulator_set< double, accumulator_set< double,
features< tag::min, tag::max, tag::mean > > acc; features< tag::min, tag::max, tag::mean > > acc;
@ -67,12 +66,8 @@ void compute_angles(Mesh* poly,Tester tester , double& mini, double& maxi, doubl
typename Traits::Point_3 b = get(vpmap, target(h, *poly)); typename Traits::Point_3 b = get(vpmap, target(h, *poly));
typename Traits::Point_3 c = get(vpmap, target(next(h, *poly), *poly)); typename Traits::Point_3 c = get(vpmap, target(next(h, *poly), *poly));
typename Traits::Vector_3 ba(b, a); typename Traits::FT ang = CGAL::approximate_angle(b,a,c);
typename Traits::Vector_3 bc(b, c); acc(CGAL::to_double(ang));
double cos_angle = (ba * bc)
/ std::sqrt(ba.squared_length() * bc.squared_length());
acc(std::acos(cos_angle) * rad_to_deg);
} }
mini = extract_result< tag::min >(acc); mini = extract_result< tag::min >(acc);
@ -281,4 +276,3 @@ void faces_aspect_ratio(Mesh* poly,
faces_aspect_ratio(poly, faces(*poly), min_altitude, mini, maxi, mean); faces_aspect_ratio(poly, faces(*poly), min_altitude, mini, maxi, mean);
} }
#endif // POLYHEDRON_DEMO_STATISTICS_HELPERS_H #endif // POLYHEDRON_DEMO_STATISTICS_HELPERS_H

View File

@ -30,7 +30,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.
void push_neighbours_of(const Vertex_const_handle start, const int ith, void push_neighbors_of(const Vertex_const_handle start, const int ith,
std::vector < Vertex_const_handle > &nextRing, std::vector < Vertex_const_handle > &nextRing,
std::vector < Vertex_const_handle > &all); std::vector < Vertex_const_handle > &all);
@ -70,7 +70,7 @@ T_PolyhedralSurf_rings(const TPoly& P)
template < class TPoly > template < class TPoly >
void T_PolyhedralSurf_rings <TPoly>:: void T_PolyhedralSurf_rings <TPoly>::
push_neighbours_of(const Vertex_const_handle start, const int ith, push_neighbors_of(const Vertex_const_handle start, const int ith,
std::vector < Vertex_const_handle > &nextRing, std::vector < Vertex_const_handle > &nextRing,
std::vector < Vertex_const_handle > &all) std::vector < Vertex_const_handle > &all)
{ {
@ -98,7 +98,7 @@ collect_ith_ring(const int ith, std::vector < Vertex_const_handle > &currentRing
typename std::vector < Vertex_const_handle >::const_iterator typename std::vector < Vertex_const_handle >::const_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); CGAL_For_all(itb, ite) push_neighbors_of(*itb, ith, nextRing, all);
} }
template <class TPoly> template <class TPoly>

View File

@ -30,7 +30,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.
void push_neighbours_of(const Vertex_const_handle start, const int ith, void push_neighbors_of(const Vertex_const_handle start, const int ith,
std::vector < Vertex_const_handle > &nextRing, std::vector < Vertex_const_handle > &nextRing,
std::vector < Vertex_const_handle > &all); std::vector < Vertex_const_handle > &all);
@ -44,7 +44,7 @@ protected:
public: public:
T_PolyhedralSurf_rings(const TPoly& P); T_PolyhedralSurf_rings(const TPoly& P);
//collect i>=1 rings : all neighbours up to the ith ring, //collect i>=1 rings : all neighbors up to the ith ring,
void collect_i_rings(const Vertex_const_handle v, void collect_i_rings(const Vertex_const_handle v,
const int ring_i, const int ring_i,
std::vector < Vertex_const_handle >& all); std::vector < Vertex_const_handle >& all);
@ -70,7 +70,7 @@ T_PolyhedralSurf_rings(const TPoly& P)
template < class TPoly > template < class TPoly >
void T_PolyhedralSurf_rings <TPoly>:: void T_PolyhedralSurf_rings <TPoly>::
push_neighbours_of(const Vertex_const_handle start, const int ith, push_neighbors_of(const Vertex_const_handle start, const int ith,
std::vector < Vertex_const_handle > &nextRing, std::vector < Vertex_const_handle > &nextRing,
std::vector < Vertex_const_handle > &all) std::vector < Vertex_const_handle > &all)
{ {
@ -98,7 +98,7 @@ collect_ith_ring(const int ith, std::vector < Vertex_const_handle > &currentRing
typename std::vector < Vertex_const_handle >::const_iterator typename std::vector < Vertex_const_handle >::const_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); CGAL_For_all(itb, ite) push_neighbors_of(*itb, ith, nextRing, all);
} }
template <class TPoly> template <class TPoly>

View File

@ -7,6 +7,3 @@ EXTRACT_ALL = false
HIDE_UNDOC_CLASSES = true HIDE_UNDOC_CLASSES = true
HIDE_UNDOC_MEMBERS = true HIDE_UNDOC_MEMBERS = true
WARN_IF_UNDOCUMENTED = false WARN_IF_UNDOCUMENTED = false
EXCLUDE = ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/internal/SMDS_3

View File

@ -419,6 +419,7 @@ bool build_triangulation_impl(Tr& tr,
if(finite_cells.empty()) if(finite_cells.empty())
{ {
if (verbose)
std::cout << "WARNING: No finite cells were provided. Only the points will be loaded."<<std::endl; std::cout << "WARNING: No finite cells were provided. Only the points will be loaded."<<std::endl;
} }
@ -438,14 +439,14 @@ bool build_triangulation_impl(Tr& tr,
success = false; success = false;
} }
else else
std::cout << "build finite cells done" << std::endl; if (verbose) std::cout << "build finite cells done" << std::endl;
if (!CGAL::SMDS_3::build_infinite_cells<Tr>(tr, incident_cells_map, verbose, allow_non_manifold)) if (!CGAL::SMDS_3::build_infinite_cells<Tr>(tr, incident_cells_map, verbose, allow_non_manifold))
{ {
if(verbose) std::cout << "build_infinite_cells went wrong" << std::endl; if(verbose) std::cout << "build_infinite_cells went wrong" << std::endl;
success = false; success = false;
} }
else else
std::cout << "build infinite cells done" << std::endl; if (verbose) std::cout << "build infinite cells done" << std::endl;
tr.tds().set_dimension(3); tr.tds().set_dimension(3);
if (!CGAL::SMDS_3::assign_neighbors<Tr>(tr, incident_cells_map, allow_non_manifold)) if (!CGAL::SMDS_3::assign_neighbors<Tr>(tr, incident_cells_map, allow_non_manifold))
{ {
@ -453,7 +454,7 @@ bool build_triangulation_impl(Tr& tr,
success = false; success = false;
} }
else else
std::cout << "assign neighbors done" << std::endl; if (verbose) std::cout << "assign neighbors done" << std::endl;
if (verbose) if (verbose)
{ {
std::cout << "built triangulation : " << std::endl; std::cout << "built triangulation : " << std::endl;

View File

@ -159,6 +159,7 @@ CGAL_add_named_parameter(random_seed_t, random_seed, random_seed)
CGAL_add_named_parameter(do_lock_mesh_t, do_lock_mesh, do_lock_mesh) CGAL_add_named_parameter(do_lock_mesh_t, do_lock_mesh, do_lock_mesh)
CGAL_add_named_parameter(do_simplify_border_t, do_simplify_border, do_simplify_border) CGAL_add_named_parameter(do_simplify_border_t, do_simplify_border, do_simplify_border)
CGAL_add_named_parameter(algorithm_t, algorithm, algorithm) CGAL_add_named_parameter(algorithm_t, algorithm, algorithm)
CGAL_add_named_parameter(use_smoothing_t, use_smoothing, use_smoothing)
//internal //internal
CGAL_add_named_parameter(weight_calculator_t, weight_calculator, weight_calculator) CGAL_add_named_parameter(weight_calculator_t, weight_calculator, weight_calculator)

View File

@ -12,6 +12,17 @@ typedef CGAL::Polygon_2<Kernel> Polygon_2;
namespace SMS = CGAL::Set_movable_separability_2; namespace SMS = CGAL::Set_movable_separability_2;
namespace casting = SMS::Single_mold_translational_casting; namespace casting = SMS::Single_mold_translational_casting;
template <typename Kernel>
inline std::pair<typename Kernel::Direction_2, typename Kernel::Direction_2>
get_segment_outer_circle(const typename Kernel::Segment_2 seg,
const CGAL::Orientation orientation)
{
typename Kernel::Direction_2 forward( seg);
typename Kernel::Direction_2 backward(-forward);
return (orientation == CGAL::CLOCKWISE) ?
std::make_pair(backward, forward) : std::make_pair(forward, backward);
}
// The main program: // The main program:
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
@ -33,8 +44,7 @@ int main(int argc, char* argv[])
++index) ++index)
{ {
auto orientation = polygon.orientation(); auto orientation = polygon.orientation();
auto segment_outer_circle = auto segment_outer_circle = get_segment_outer_circle<Kernel>(*e_it, orientation);
SMS::internal::get_segment_outer_circle<Kernel>(*e_it, orientation);
auto d = segment_outer_circle.first; auto d = segment_outer_circle.first;
d = d.perpendicular(CGAL::CLOCKWISE); d = d.perpendicular(CGAL::CLOCKWISE);
auto res = casting::is_pullout_direction(polygon, e_it, d); auto res = casting::is_pullout_direction(polygon, e_it, d);

View File

@ -242,7 +242,12 @@ class Eigen_solver_traits<Eigen::BiCGSTAB<Eigen_sparse_matrix<double>::EigenType
public: public:
typedef EigenSolverT Solver; typedef EigenSolverT Solver;
typedef Scalar NT; typedef Scalar NT;
#ifdef DOXYGEN_RUNNING
typedef unspecified_type Matrix;
#else
typedef internal::Get_eigen_matrix<EigenSolverT,NT>::type Matrix; typedef internal::Get_eigen_matrix<EigenSolverT,NT>::type Matrix;
#endif
typedef Eigen_vector<Scalar> Vector; typedef Eigen_vector<Scalar> Vector;
// Public operations // Public operations

View File

@ -413,8 +413,8 @@ namespace nanoflann
checks(checks_IGNORED_), eps(eps_), sorted(sorted_) {} checks(checks_IGNORED_), eps(eps_), sorted(sorted_) {}
int checks; //!< Ignored parameter (Kept for compatibility with the FLANN interface). int checks; //!< Ignored parameter (Kept for compatibility with the FLANN interface).
float eps; //!< search for eps-approximate neighbours (default: 0) float eps; //!< search for eps-approximate neighbors (default: 0)
bool sorted; //!< only for radius search, require neighbours sorted by distance (default: true) bool sorted; //!< only for radius search, require neighbors sorted by distance (default: true)
}; };
/** @} */ /** @} */
@ -823,7 +823,7 @@ namespace nanoflann
}; };
/** /**
* Array of k-d trees used to find neighbours. * Array of k-d trees used to find neighbors.
*/ */
NodePtr root_node; NodePtr root_node;
typedef BranchStruct<NodePtr, DistanceType> BranchSt; typedef BranchStruct<NodePtr, DistanceType> BranchSt;

View File

@ -6,6 +6,7 @@
\example Spatial_searching/fuzzy_range_query.cpp \example Spatial_searching/fuzzy_range_query.cpp
\example Spatial_searching/general_neighbor_searching.cpp \example Spatial_searching/general_neighbor_searching.cpp
\example Spatial_searching/iso_rectangle_2_query.cpp \example Spatial_searching/iso_rectangle_2_query.cpp
\example Spatial_searching/iso_rectangle_2_query_projection.cpp
\example Spatial_searching/nearest_neighbor_searching.cpp \example Spatial_searching/nearest_neighbor_searching.cpp
\example Spatial_searching/searching_with_circular_query.cpp \example Spatial_searching/searching_with_circular_query.cpp
\example Spatial_searching/searching_surface_mesh_vertices.cpp \example Spatial_searching/searching_surface_mesh_vertices.cpp

View File

@ -28,6 +28,8 @@ create_single_source_cgal_program("distance_browsing.cpp")
create_single_source_cgal_program("iso_rectangle_2_query.cpp") create_single_source_cgal_program("iso_rectangle_2_query.cpp")
create_single_source_cgal_program("iso_rectangle_2_query_projection.cpp")
create_single_source_cgal_program("nearest_neighbor_searching.cpp") create_single_source_cgal_program("nearest_neighbor_searching.cpp")
create_single_source_cgal_program("searching_with_circular_query.cpp") create_single_source_cgal_program("searching_with_circular_query.cpp")

View File

@ -46,7 +46,7 @@ int main()
// using value 0.1 for fuzziness parameter // using value 0.1 for fuzziness parameter
Fuzzy_iso_box approximate_range(p, q, 0.1); Fuzzy_iso_box approximate_range(p, q, 0.1);
tree.search(std::back_inserter( result ), approximate_range); tree.search(std::back_inserter( result ), approximate_range);
std::cout << "The points in the fuzzy box [[0.1, 0.3], [0.6, 0.9]]^2 are: " << std::endl; std::cout << "The points in the fuzzy box [[0.1, 0.3], [0.6, 0.8]]^2 are: " << std::endl;
std::copy (result.begin(), result.end(), std::ostream_iterator<Point_d>(std::cout,"\n") ); std::copy (result.begin(), result.end(), std::ostream_iterator<Point_d>(std::cout,"\n") );
std::cout << std::endl; std::cout << std::endl;
return 0; return 0;

View File

@ -0,0 +1,72 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Kd_tree.h>
#include <CGAL/point_generators_3.h>
#include <CGAL/algorithm.h>
#include <CGAL/Fuzzy_iso_box.h>
#include <CGAL/Search_traits_2.h>
// Point_3 to Point_2 projection on the fly
template<class K>
struct Projection_xy_property_map
{
typedef typename K::Point_3 key_type;
typedef typename K::Point_2 value_type;
typedef value_type reference;
typedef boost::readable_property_map_tag category;
friend value_type get(Projection_xy_property_map<K>, const key_type& k)
{
return value_type(k.x(), k.y());
}
};
typedef CGAL::Simple_cartesian<double> K;
typedef K::Point_2 Point_2;
typedef K::Point_3 Point_3;
typedef CGAL::Random_points_in_cube_3<Point_3> Random_points_iterator;
typedef CGAL::Counting_iterator<Random_points_iterator> N_Random_points_iterator;
typedef CGAL::Search_traits_2<K>Traits_base;
typedef CGAL::Search_traits_adapter<Point_3, Projection_xy_property_map<K>, Traits_base> Traits;
typedef CGAL::Kd_tree<Traits> Tree;
typedef CGAL::Fuzzy_iso_box<Traits> Fuzzy_iso_box;
int main()
{
const int N = 1000;
std::list<Point_3> points;
points.push_back(Point_3(0, 0, 0));
Tree tree;
Random_points_iterator rpg;
for(int i = 0; i < N; i++)
tree.insert(*rpg++);
std::list<Point_3> result;
// define 2D range query
Point_2 p(0.2, 0.2);
Point_2 q(0.7, 0.7);
// Searching an exact range
// using default value 0.0 for epsilon fuzziness paramater
Fuzzy_iso_box exact_range(p,q);
tree.search( std::back_inserter( result ), exact_range);
std::cout << "The points in the box [0.2, 0.7]^2 are: " << std::endl;
std::copy (result.begin(), result.end(), std::ostream_iterator<Point_3>(std::cout,"\n") );
std::cout << std::endl;
result.clear();
// Searching a fuzzy range
// using value 0.1 for fuzziness paramater
Fuzzy_iso_box approximate_range(p, q, 0.1);
tree.search(std::back_inserter( result ), approximate_range);
std::cout << "The points in the fuzzy box [[0.1, 0.3], [0.6, 0.8]]^2 are: " << std::endl;
std::copy (result.begin(), result.end(), std::ostream_iterator<Point_3>(std::cout,"\n") );
std::cout << std::endl;
return 0;
}

View File

@ -264,7 +264,7 @@ namespace CGAL {
FT distance_to_root; FT distance_to_root;
bool search_nearest_neighbour; bool search_nearest_neighbor;
FT rd; FT rd;
@ -278,8 +278,8 @@ namespace CGAL {
bool search_nearest; bool search_nearest;
Priority_higher(bool search_the_nearest_neighbour) Priority_higher(bool search_the_nearest_neighbor)
: search_nearest(search_the_nearest_neighbour) : search_nearest(search_the_nearest_neighbor)
{} {}
//highest priority is smallest distance //highest priority is smallest distance
@ -296,8 +296,8 @@ namespace CGAL {
bool search_nearest; bool search_nearest;
Distance_smaller(bool search_the_nearest_neighbour) Distance_smaller(bool search_the_nearest_neighbor)
:search_nearest(search_the_nearest_neighbour) :search_nearest(search_the_nearest_neighbor)
{} {}
//highest priority is smallest distance //highest priority is smallest distance
@ -325,19 +325,19 @@ namespace CGAL {
int number_of_internal_nodes_visited; int number_of_internal_nodes_visited;
int number_of_leaf_nodes_visited; int number_of_leaf_nodes_visited;
int number_of_items_visited; int number_of_items_visited;
int number_of_neighbours_computed; int number_of_neighbors_computed;
// constructor // constructor
Iterator_implementation(const Tree& tree, const Query_item& q,const Distance& tr, Iterator_implementation(const Tree& tree, const Query_item& q,const Distance& tr,
FT Eps, bool search_nearest) FT Eps, bool search_nearest)
: query_point(q), search_nearest_neighbour(search_nearest), : query_point(q), search_nearest_neighbor(search_nearest),
m_distance_helper(tr, tree.traits()), m_distance_helper(tr, tree.traits()),
m_tree(tree), m_tree(tree),
PriorityQueue(Priority_higher(search_nearest)), PriorityQueue(Priority_higher(search_nearest)),
Item_PriorityQueue(Distance_smaller(search_nearest)), Item_PriorityQueue(Distance_smaller(search_nearest)),
distance(tr), reference_count(1), number_of_internal_nodes_visited(0), distance(tr), reference_count(1), number_of_internal_nodes_visited(0),
number_of_leaf_nodes_visited(0), number_of_items_visited(0), number_of_leaf_nodes_visited(0), number_of_items_visited(0),
number_of_neighbours_computed(0) number_of_neighbors_computed(0)
{ {
if (tree.empty()) return; if (tree.empty()) return;
@ -365,7 +365,7 @@ namespace CGAL {
// rd is the distance of the top of the priority queue to q // rd is the distance of the top of the priority queue to q
rd=The_Root->second; rd=The_Root->second;
Compute_the_next_nearest_neighbour(); Compute_the_next_nearest_neighbor();
} }
// * operator // * operator
@ -380,7 +380,7 @@ namespace CGAL {
operator++() operator++()
{ {
Delete_the_current_item_top(); Delete_the_current_item_top();
Compute_the_next_nearest_neighbour(); Compute_the_next_nearest_neighbor();
return *this; return *this;
} }
@ -405,7 +405,7 @@ namespace CGAL {
s << "Number of points visited:" << s << "Number of points visited:" <<
number_of_items_visited << std::endl; number_of_items_visited << std::endl;
s << "Number of neighbors computed:" << s << "Number of neighbors computed:" <<
number_of_neighbours_computed << std::endl; number_of_neighbors_computed << std::endl;
return s; return s;
} }
@ -459,21 +459,21 @@ namespace CGAL {
// old top of PriorityQueue has been processed, // old top of PriorityQueue has been processed,
// hence update rd // hence update rd
bool next_neighbour_found; bool next_neighbor_found;
if (!(PriorityQueue.empty())) if (!(PriorityQueue.empty()))
{ {
rd = PriorityQueue.top()->second; rd = PriorityQueue.top()->second;
next_neighbour_found = (search_furthest ? next_neighbor_found = (search_furthest ?
multiplication_factor*rd < Item_PriorityQueue.top()->second multiplication_factor*rd < Item_PriorityQueue.top()->second
: multiplication_factor*rd > Item_PriorityQueue.top()->second); : multiplication_factor*rd > Item_PriorityQueue.top()->second);
} }
else // priority queue empty => last neighbour found else // priority queue empty => last neighbor found
{ {
next_neighbour_found = true; next_neighbor_found = true;
} }
number_of_neighbours_computed++; number_of_neighbors_computed++;
return next_neighbour_found; return next_neighbor_found;
} }
// Without cache // Without cache
@ -494,37 +494,37 @@ namespace CGAL {
// old top of PriorityQueue has been processed, // old top of PriorityQueue has been processed,
// hence update rd // hence update rd
bool next_neighbour_found; bool next_neighbor_found;
if (!(PriorityQueue.empty())) if (!(PriorityQueue.empty()))
{ {
rd = PriorityQueue.top()->second; rd = PriorityQueue.top()->second;
next_neighbour_found = (search_furthest ? next_neighbor_found = (search_furthest ?
multiplication_factor*rd < Item_PriorityQueue.top()->second multiplication_factor*rd < Item_PriorityQueue.top()->second
: multiplication_factor*rd > Item_PriorityQueue.top()->second); : multiplication_factor*rd > Item_PriorityQueue.top()->second);
} }
else // priority queue empty => last neighbour found else // priority queue empty => last neighbor found
{ {
next_neighbour_found = true; next_neighbor_found = true;
} }
number_of_neighbours_computed++; number_of_neighbors_computed++;
return next_neighbour_found; return next_neighbor_found;
} }
void void
Compute_the_next_nearest_neighbour() Compute_the_next_nearest_neighbor()
{ {
// compute the next item // compute the next item
bool next_neighbour_found=false; bool next_neighbor_found=false;
if (!(Item_PriorityQueue.empty())) { if (!(Item_PriorityQueue.empty())) {
if (search_nearest_neighbour) if (search_nearest_neighbor)
next_neighbour_found = next_neighbor_found =
(multiplication_factor*rd > Item_PriorityQueue.top()->second); (multiplication_factor*rd > Item_PriorityQueue.top()->second);
else else
next_neighbour_found = next_neighbor_found =
(rd < multiplication_factor*Item_PriorityQueue.top()->second); (rd < multiplication_factor*Item_PriorityQueue.top()->second);
} }
while ((!next_neighbour_found) && (!PriorityQueue.empty())) { while ((!next_neighbor_found) && (!PriorityQueue.empty())) {
Cell_with_distance* The_node_top = PriorityQueue.top(); Cell_with_distance* The_node_top = PriorityQueue.top();
Node_const_handle N = The_node_top->first->node(); Node_const_handle N = The_node_top->first->node();
@ -544,7 +544,7 @@ namespace CGAL {
Node_box* upper_box = new Node_box(*B); Node_box* upper_box = new Node_box(*B);
lower_box->split(*upper_box,new_cut_dim, new_cut_val); lower_box->split(*upper_box,new_cut_dim, new_cut_val);
delete B; delete B;
if (search_nearest_neighbour) { if (search_nearest_neighbor) {
FT distance_to_box_lower = FT distance_to_box_lower =
distance.min_distance_to_rectangle(query_point, *lower_box); distance.min_distance_to_rectangle(query_point, *lower_box);
FT distance_to_box_upper = FT distance_to_box_upper =
@ -597,12 +597,15 @@ namespace CGAL {
number_of_leaf_nodes_visited++; number_of_leaf_nodes_visited++;
if (node->size() > 0) { if (node->size() > 0) {
typename internal::Has_points_cache<Tree, internal::has_Enable_points_cache<Tree>::type::value>::type dummy; typename internal::Has_points_cache<Tree, internal::has_Enable_points_cache<Tree>::type::value>::type dummy;
next_neighbour_found = search_in_leaf(node, dummy, !search_nearest_neighbour); next_neighbor_found = search_in_leaf(node, dummy, !search_nearest_neighbor);
} }
} // next_neighbour_found or priority queue is empty } // next_neighbor_found or priority queue is empty
// in the latter case also the item priority queue is empty // in the latter case also the item priority queue is empty
} }
CGAL_DEPRECATED void Compute_the_next_nearest_neighbour()
{ void Compute_the_next_nearest_neighbor(); }
}; // class Iterator_implementation }; // class Iterator_implementation
}; // class iterator }; // class iterator
}; // class }; // class

View File

@ -65,7 +65,7 @@ namespace CGAL {
SearchTraits traits; SearchTraits traits;
public: public:
int number_of_neighbours_computed; int number_of_neighbors_computed;
int number_of_internal_nodes_visited; int number_of_internal_nodes_visited;
int number_of_leaf_nodes_visited; int number_of_leaf_nodes_visited;
int number_of_items_visited; int number_of_items_visited;
@ -85,7 +85,7 @@ namespace CGAL {
FT distance_to_root; FT distance_to_root;
bool search_nearest_neighbour; bool search_nearest_neighbor;
FT rd; FT rd;
@ -97,8 +97,8 @@ namespace CGAL {
bool search_nearest; bool search_nearest;
Priority_higher(bool search_the_nearest_neighbour) Priority_higher(bool search_the_nearest_neighbor)
: search_nearest(search_the_nearest_neighbour) : search_nearest(search_the_nearest_neighbor)
{} {}
//highest priority is smallest distance //highest priority is smallest distance
@ -115,8 +115,8 @@ namespace CGAL {
bool search_nearest; bool search_nearest;
Distance_smaller(bool search_the_nearest_neighbour) Distance_smaller(bool search_the_nearest_neighbor)
: search_nearest(search_the_nearest_neighbour) : search_nearest(search_the_nearest_neighbor)
{} {}
//highest priority is smallest distance //highest priority is smallest distance
@ -144,12 +144,12 @@ namespace CGAL {
// constructor // constructor
Iterator_implementation(const Tree& tree,const Query_item& q, const Distance& tr, Iterator_implementation(const Tree& tree,const Query_item& q, const Distance& tr,
FT Eps=FT(0.0), bool search_nearest=true) FT Eps=FT(0.0), bool search_nearest=true)
: traits(tree.traits()),number_of_neighbours_computed(0), number_of_internal_nodes_visited(0), : traits(tree.traits()),number_of_neighbors_computed(0), number_of_internal_nodes_visited(0),
number_of_leaf_nodes_visited(0), number_of_items_visited(0), number_of_leaf_nodes_visited(0), number_of_items_visited(0),
orthogonal_distance_instance(tr), orthogonal_distance_instance(tr),
m_distance_helper(orthogonal_distance_instance, traits), m_distance_helper(orthogonal_distance_instance, traits),
multiplication_factor(orthogonal_distance_instance.transformed_distance(FT(1.0)+Eps)), multiplication_factor(orthogonal_distance_instance.transformed_distance(FT(1.0)+Eps)),
query_point(q), search_nearest_neighbour(search_nearest), query_point(q), search_nearest_neighbor(search_nearest),
m_tree(tree), m_tree(tree),
PriorityQueue(Priority_higher(search_nearest)), Item_PriorityQueue(Distance_smaller(search_nearest)), PriorityQueue(Priority_higher(search_nearest)), Item_PriorityQueue(Distance_smaller(search_nearest)),
reference_count(1) reference_count(1)
@ -175,7 +175,7 @@ namespace CGAL {
// rd is the distance of the top of the priority queue to q // rd is the distance of the top of the priority queue to q
rd=std::get<1>(*The_Root); rd=std::get<1>(*The_Root);
Compute_the_next_nearest_neighbour(); Compute_the_next_nearest_neighbor();
} }
else{ else{
distance_to_root= distance_to_root=
@ -187,7 +187,7 @@ namespace CGAL {
// rd is the distance of the top of the priority queue to q // rd is the distance of the top of the priority queue to q
rd=std::get<1>(*The_Root); rd=std::get<1>(*The_Root);
Compute_the_next_furthest_neighbour(); Compute_the_next_furthest_neighbor();
} }
@ -205,10 +205,10 @@ namespace CGAL {
operator++() operator++()
{ {
Delete_the_current_item_top(); Delete_the_current_item_top();
if(search_nearest_neighbour) if(search_nearest_neighbor)
Compute_the_next_nearest_neighbour(); Compute_the_next_nearest_neighbor();
else else
Compute_the_next_furthest_neighbour(); Compute_the_next_furthest_neighbor();
return *this; return *this;
} }
@ -233,7 +233,7 @@ namespace CGAL {
s << "Number of items visited:" s << "Number of items visited:"
<< number_of_items_visited << std::endl; << number_of_items_visited << std::endl;
s << "Number of neighbors computed:" s << "Number of neighbors computed:"
<< number_of_neighbours_computed << std::endl; << number_of_neighbors_computed << std::endl;
return s; return s;
} }
@ -287,21 +287,21 @@ namespace CGAL {
// old top of PriorityQueue has been processed, // old top of PriorityQueue has been processed,
// hence update rd // hence update rd
bool next_neighbour_found; bool next_neighbor_found;
if (!(PriorityQueue.empty())) if (!(PriorityQueue.empty()))
{ {
rd = std::get<1>(*PriorityQueue.top()); rd = std::get<1>(*PriorityQueue.top());
next_neighbour_found = (search_furthest ? next_neighbor_found = (search_furthest ?
multiplication_factor*rd < Item_PriorityQueue.top()->second multiplication_factor*rd < Item_PriorityQueue.top()->second
: multiplication_factor*rd > Item_PriorityQueue.top()->second); : multiplication_factor*rd > Item_PriorityQueue.top()->second);
} }
else // priority queue empty => last neighbor found else // priority queue empty => last neighbor found
{ {
next_neighbour_found = true; next_neighbor_found = true;
} }
number_of_neighbours_computed++; number_of_neighbors_computed++;
return next_neighbour_found; return next_neighbor_found;
} }
// Without cache // Without cache
@ -322,37 +322,37 @@ namespace CGAL {
// old top of PriorityQueue has been processed, // old top of PriorityQueue has been processed,
// hence update rd // hence update rd
bool next_neighbour_found; bool next_neighbor_found;
if (!(PriorityQueue.empty())) if (!(PriorityQueue.empty()))
{ {
rd = std::get<1>(*PriorityQueue.top()); rd = std::get<1>(*PriorityQueue.top());
next_neighbour_found = (search_furthest ? next_neighbor_found = (search_furthest ?
multiplication_factor*rd < Item_PriorityQueue.top()->second multiplication_factor*rd < Item_PriorityQueue.top()->second
: multiplication_factor*rd > Item_PriorityQueue.top()->second); : multiplication_factor*rd > Item_PriorityQueue.top()->second);
} }
else // priority queue empty => last neighbour found else // priority queue empty => last neighbor found
{ {
next_neighbour_found=true; next_neighbor_found=true;
} }
number_of_neighbours_computed++; number_of_neighbors_computed++;
return next_neighbour_found; return next_neighbor_found;
} }
void void
Compute_the_next_nearest_neighbour() Compute_the_next_nearest_neighbor()
{ {
// compute the next item // compute the next item
bool next_neighbour_found=false; bool next_neighbor_found=false;
if (!(Item_PriorityQueue.empty())) { if (!(Item_PriorityQueue.empty())) {
next_neighbour_found= next_neighbor_found=
(multiplication_factor*rd > Item_PriorityQueue.top()->second); (multiplication_factor*rd > Item_PriorityQueue.top()->second);
} }
typename SearchTraits::Construct_cartesian_const_iterator_d construct_it=traits.construct_cartesian_const_iterator_d_object(); typename SearchTraits::Construct_cartesian_const_iterator_d construct_it=traits.construct_cartesian_const_iterator_d_object();
typename SearchTraits::Cartesian_const_iterator_d query_point_it = construct_it(query_point); typename SearchTraits::Cartesian_const_iterator_d query_point_it = construct_it(query_point);
// otherwise browse the tree further // otherwise browse the tree further
while ((!next_neighbour_found) && (!PriorityQueue.empty())) { while ((!next_neighbor_found) && (!PriorityQueue.empty())) {
Node_with_distance* The_node_top=PriorityQueue.top(); Node_with_distance* The_node_top=PriorityQueue.top();
Node_const_handle N= std::get<0>(*The_node_top); Node_const_handle N= std::get<0>(*The_node_top);
dists = std::get<2>(*The_node_top); dists = std::get<2>(*The_node_top);
@ -398,26 +398,29 @@ namespace CGAL {
number_of_leaf_nodes_visited++; number_of_leaf_nodes_visited++;
if (node->size() > 0) { if (node->size() > 0) {
typename internal::Has_points_cache<Tree, internal::has_Enable_points_cache<Tree>::type::value>::type dummy; typename internal::Has_points_cache<Tree, internal::has_Enable_points_cache<Tree>::type::value>::type dummy;
next_neighbour_found = search_in_leaf(node, dummy, false); next_neighbor_found = search_in_leaf(node, dummy, false);
} }
} // next_neighbour_found or priority queue is empty } // next_neighbor_found or priority queue is empty
// in the latter case also the item priority queue is empty // in the latter case also the item priority queue is empty
} }
CGAL_DEPRECATED void Compute_the_next_nearest_neighbour()
{ Compute_the_next_nearest_neighbor(); }
void void
Compute_the_next_furthest_neighbour() Compute_the_next_furthest_neighbor()
{ {
// compute the next item // compute the next item
bool next_neighbour_found=false; bool next_neighbor_found=false;
if (!(Item_PriorityQueue.empty())) { if (!(Item_PriorityQueue.empty())) {
next_neighbour_found= next_neighbor_found=
(rd < multiplication_factor*Item_PriorityQueue.top()->second); (rd < multiplication_factor*Item_PriorityQueue.top()->second);
} }
typename SearchTraits::Construct_cartesian_const_iterator_d construct_it=traits.construct_cartesian_const_iterator_d_object(); typename SearchTraits::Construct_cartesian_const_iterator_d construct_it=traits.construct_cartesian_const_iterator_d_object();
typename SearchTraits::Cartesian_const_iterator_d query_point_it = construct_it(query_point); typename SearchTraits::Cartesian_const_iterator_d query_point_it = construct_it(query_point);
// otherwise browse the tree further // otherwise browse the tree further
while ((!next_neighbour_found) && (!PriorityQueue.empty())) { while ((!next_neighbor_found) && (!PriorityQueue.empty())) {
Node_with_distance* The_node_top=PriorityQueue.top(); Node_with_distance* The_node_top=PriorityQueue.top();
Node_const_handle N= std::get<0>(*The_node_top); Node_const_handle N= std::get<0>(*The_node_top);
dists = std::get<2>(*The_node_top); dists = std::get<2>(*The_node_top);
@ -462,11 +465,14 @@ namespace CGAL {
number_of_leaf_nodes_visited++; number_of_leaf_nodes_visited++;
if (node->size() > 0) { if (node->size() > 0) {
typename internal::Has_points_cache<Tree, internal::has_Enable_points_cache<Tree>::type::value>::type dummy; typename internal::Has_points_cache<Tree, internal::has_Enable_points_cache<Tree>::type::value>::type dummy;
next_neighbour_found = search_in_leaf(node, dummy, true); next_neighbor_found = search_in_leaf(node, dummy, true);
} }
} // next_neighbour_found or priority queue is empty } // next_neighbor_found or priority queue is empty
// in the latter case also the item priority queue is empty // in the latter case also the item priority queue is empty
} }
CGAL_DEPRECATED void Compute_the_next_furthest_neighbour()
{ Compute_the_next_furthest_neighbor(); }
}; // class Iterator_implementaion }; // class Iterator_implementaion

View File

@ -138,14 +138,14 @@ public:
typedef typename boost::property_traits<PointPropertyMap>::value_type typedef typename boost::property_traits<PointPropertyMap>::value_type
Point; Point;
std::shared_ptr<Point> point; Point point;
std::size_t idx; std::size_t idx = 0;
public: public:
No_lvalue_iterator() : point(NULL), idx(0) { } No_lvalue_iterator() : point() { }
No_lvalue_iterator(const Point& point) : point(new Point(point)), idx(0) { } No_lvalue_iterator(const Point& point) : point(point) { }
No_lvalue_iterator(const Point& point, int) : point(new Point(point)), idx(Base::Dimension::value) { } No_lvalue_iterator(const Point& point, int) : point(point), idx(Base::Dimension::value) { }
private: private:
@ -153,18 +153,15 @@ public:
void increment() void increment()
{ {
++idx; ++idx;
CGAL_assertion(point != std::shared_ptr<Point>());
} }
void decrement() void decrement()
{ {
--idx; --idx;
CGAL_assertion(point != std::shared_ptr<Point>());
} }
void advance(std::ptrdiff_t n) void advance(std::ptrdiff_t n)
{ {
idx += n; idx += n;
CGAL_assertion(point != std::shared_ptr<Point>());
} }
std::ptrdiff_t distance_to(const No_lvalue_iterator& other) const std::ptrdiff_t distance_to(const No_lvalue_iterator& other) const
@ -181,7 +178,7 @@ public:
dereference() const dereference() const
{ {
// Point::operator[] takes an int as parameter... // Point::operator[] takes an int as parameter...
return const_cast<Dereference_type&>((*point)[static_cast<int>(idx)]); return const_cast<Dereference_type&>(point[static_cast<int>(idx)]);
} }
}; };

View File

@ -60,8 +60,8 @@ protected:
public: public:
Distance_larger(bool search_the_nearest_neighbour) Distance_larger(bool search_the_nearest_neighbor)
: search_nearest(search_the_nearest_neighbour) : search_nearest(search_the_nearest_neighbor)
{} {}
bool operator()(const Point_ptr_with_transformed_distance& p1, bool operator()(const Point_ptr_with_transformed_distance& p1,

View File

@ -71,21 +71,21 @@ void run()
typename K_search::iterator it = oins.begin(); typename K_search::iterator it = oins.begin();
typename K_search::Point_with_transformed_distance pd = *it; typename K_search::Point_with_transformed_distance pd = *it;
points2.push_back(get_point(pd.first)); points2.push_back(get_point(pd.first));
if(CGAL::squared_distance(query,get_point(pd.first)) != pd.second){ if(abs(CGAL::squared_distance(query, get_point(pd.first)) - pd.second) >= 0.000000001){
std::cout << "different distances: " << CGAL::squared_distance(query,get_point(pd.first)) << " != " << pd.second << std::endl; std::cout << "different distances: " << CGAL::squared_distance(query,get_point(pd.first)) << " != " << pd.second << std::endl;
} }
assert(CGAL_IA_FORCE_TO_DOUBLE(CGAL::squared_distance(query,get_point(pd.first))) == pd.second); assert(abs(CGAL::squared_distance(query, get_point(pd.first)) - pd.second) < 0.000000001);
it++; it++;
for(; it != oins.end();it++){ for(; it != oins.end();it++){
typename K_search::Point_with_transformed_distance qd = *it; typename K_search::Point_with_transformed_distance qd = *it;
assert(pd.second <= qd.second); assert(pd.second <= qd.second);
pd = qd; pd = qd;
points2.push_back(get_point(pd.first)); points2.push_back(get_point(pd.first));
if(CGAL_IA_FORCE_TO_DOUBLE(CGAL::squared_distance(query,get_point(pd.first))) != pd.second){ if(abs(CGAL::squared_distance(query, get_point(pd.first)) - pd.second) >= 0.000000001){
std::cout << "different distances: " << CGAL::squared_distance(query,get_point(pd.first)) << " != " << pd.second << std::endl; std::cout << "different distances: " << CGAL::squared_distance(query,get_point(pd.first)) << " != " << pd.second << std::endl;
} }
assert(CGAL_IA_FORCE_TO_DOUBLE(CGAL::squared_distance(query,get_point(pd.first))) == pd.second); assert(abs(CGAL::squared_distance(query, get_point(pd.first)) - pd.second) < 0.000000001);
} }
@ -176,6 +176,7 @@ bool search(bool nearest)
int int
main() { main() {
std::cout << std::setprecision(17);
bool OK=true; bool OK=true;
std::cout << "Testing Incremental_neighbor_search\n"; std::cout << "Testing Incremental_neighbor_search\n";
run<Incremental_neighbor_search>(); run<Incremental_neighbor_search>();

View File

@ -60,20 +60,23 @@ struct Splitter_test {
typename Orthogonal_incremental_neighbor_search::iterator it = oins.begin(); typename Orthogonal_incremental_neighbor_search::iterator it = oins.begin();
Point_with_transformed_distance pd = *it; Point_with_transformed_distance pd = *it;
points2.push_back(get_point(pd.first)); points2.push_back(get_point(pd.first));
if(CGAL::squared_distance(query,get_point(pd.first)) != pd.second){
std::cout << std::setprecision(17);
if(abs(CGAL::squared_distance(query, get_point(pd.first)) - pd.second) >= 0.000000001){
std::cout << CGAL::squared_distance(query,get_point(pd.first)) << " != " << pd.second << std::endl; std::cout << CGAL::squared_distance(query,get_point(pd.first)) << " != " << pd.second << std::endl;
} }
assert(CGAL_IA_FORCE_TO_DOUBLE(CGAL::squared_distance(query,get_point(pd.first))) == pd.second); assert(abs(CGAL::squared_distance(query,get_point(pd.first)) - pd.second) < 0.000000001);
it++; it++;
for(; it != oins.end();it++){ for(; it != oins.end();it++){
Point_with_transformed_distance qd = *it; Point_with_transformed_distance qd = *it;
assert(pd.second <= qd.second); assert(pd.second <= qd.second);
pd = qd; pd = qd;
points2.push_back(get_point(pd.first)); points2.push_back(get_point(pd.first));
if(CGAL_IA_FORCE_TO_DOUBLE(CGAL::squared_distance(query,get_point(pd.first))) != pd.second){ if(abs(CGAL::squared_distance(query, get_point(pd.first)) - pd.second) >= 0.000000001){
std::cout << CGAL::squared_distance(query,get_point(pd.first)) << " != " << pd.second << std::endl; std::cout << CGAL::squared_distance(query,get_point(pd.first)) << " != " << pd.second << std::endl;
} }
assert(CGAL_IA_FORCE_TO_DOUBLE(CGAL::squared_distance(query,get_point(pd.first))) == pd.second); assert(abs(CGAL::squared_distance(query, get_point(pd.first)) - pd.second) < 0.000000001);
} }
std::sort(points.begin(),points.end()); std::sort(points.begin(),points.end());
std::sort(points2.begin(),points2.end()); std::sort(points2.begin(),points2.end());

View File

@ -137,43 +137,14 @@ private:
return K().construct_segment_2_object()(s,t); return K().construct_segment_2_object()(s,t);
} }
Trisegment_2_ptr CreateTrisegment ( Triedge const& aTriedge ) const Trisegment_2_ptr GetTrisegment ( Vertex_const_handle aNode ) const ;
{
CGAL_precondition( aTriedge.is_valid() ) ;
if ( aTriedge.is_skeleton() )
{
return Construct_ss_trisegment_2(mTraits)(CreateSegment(aTriedge.e0())
,CreateSegment(aTriedge.e1())
,CreateSegment(aTriedge.e2())
);
}
else
{
return Trisegment_2_ptr() ;
}
}
Trisegment_2_ptr CreateTrisegment ( Vertex_const_handle aNode ) const ;
Vertex_const_handle GetSeedVertex ( Vertex_const_handle aNode
, Halfedge_const_handle aBisector
, Halfedge_const_handle aEa
, Halfedge_const_handle aEb
) const ;
bool Is_bisector_defined_by ( Halfedge_const_handle aBisector, Halfedge_const_handle aEa, Halfedge_const_handle aEb ) const
{
return ( aBisector->defining_contour_edge() == aEa && aBisector->opposite()->defining_contour_edge() == aEb )
|| ( aBisector->defining_contour_edge() == aEb && aBisector->opposite()->defining_contour_edge() == aEa ) ;
}
Comparison_result Compare_offset_against_event_time( FT aT, Vertex_const_handle aNode ) const Comparison_result Compare_offset_against_event_time( FT aT, Vertex_const_handle aNode ) const
{ {
CGAL_precondition( aNode->is_skeleton() ) ; CGAL_precondition( aNode->is_skeleton() ) ;
Comparison_result r = aNode->has_infinite_time() ? SMALLER Comparison_result r = aNode->has_infinite_time() ? SMALLER
: static_cast<Comparison_result>(Compare_offset_against_event_time_2(mTraits)(aT,CreateTrisegment(aNode))); : static_cast<Comparison_result>(Compare_offset_against_event_time_2(mTraits)(aT,GetTrisegment(aNode)));
return r ; return r ;
} }
@ -199,8 +170,7 @@ public:
CGAL_assertion ( lNodeT->is_skeleton() ) ; CGAL_assertion ( lNodeT->is_skeleton() ) ;
Vertex_const_handle lSeedNode = aBisector->slope() == POSITIVE ? lNodeS : lNodeT ; Vertex_const_handle lSeedNode = aBisector->slope() == POSITIVE ? lNodeS : lNodeT ;
lSeedEvent = GetTrisegment(lSeedNode) ;
lSeedEvent = CreateTrisegment(lSeedNode) ;
CGAL_POLYOFFSET_TRACE(3,"Seed node for " << e2str(*aBisector) << " is " << v2str(*lSeedNode) << " event=" << lSeedEvent ) ; CGAL_POLYOFFSET_TRACE(3,"Seed node for " << e2str(*aBisector) << " is " << v2str(*lSeedNode) << " event=" << lSeedEvent ) ;
} }

View File

@ -66,7 +66,7 @@ Polygon_offset_builder_2<Ss,Gt,Cont,Visitor>::LocateHook( FT
Halfedge_const_handle lNext = aBisector->next(); Halfedge_const_handle lNext = aBisector->next();
CGAL_POLYOFFSET_TRACE(2,"Testing hook on " << e2str(*aBisector) ) ; CGAL_POLYOFFSET_TRACE(2,"Testing hook on " << e2str(*aBisector) ) ;
CGAL_POLYOFFSET_TRACE(4, "Next: " << e2str(*lNext) << " - Prev: " << e2str(*lPrev) ) ; CGAL_POLYOFFSET_TRACE(4, "Next: " << e2str(*lNext) << " ; Prev: " << e2str(*lPrev) ) ;
if ( !IsVisited(aBisector) ) if ( !IsVisited(aBisector) )
{ {
@ -82,6 +82,9 @@ Polygon_offset_builder_2<Ss,Gt,Cont,Visitor>::LocateHook( FT
Comparison_result lTimeWrtSrcTime = lPrev->is_bisector() ? Compare_offset_against_event_time(aTime,lPrev ->vertex()) : LARGER ; Comparison_result lTimeWrtSrcTime = lPrev->is_bisector() ? Compare_offset_against_event_time(aTime,lPrev ->vertex()) : LARGER ;
Comparison_result lTimeWrtTgtTime = lNext->is_bisector() ? Compare_offset_against_event_time(aTime,aBisector->vertex()) : LARGER ; Comparison_result lTimeWrtTgtTime = lNext->is_bisector() ? Compare_offset_against_event_time(aTime,aBisector->vertex()) : LARGER ;
CGAL_POLYOFFSET_TRACE(3," lPrev->is_bisector(): " << lPrev->is_bisector() << " lNext->is_bisector(): " << lNext->is_bisector());
CGAL_POLYOFFSET_TRACE(3," lPrev->vertex()->time(): " << lPrev->vertex()->time());
CGAL_POLYOFFSET_TRACE(3," aBisector->vertex()->time(): " << aBisector->vertex()->time());
CGAL_POLYOFFSET_TRACE(3," TimeWrtSrcTime: " << lTimeWrtSrcTime << " TimeWrtTgtTime: " << lTimeWrtTgtTime ) ; CGAL_POLYOFFSET_TRACE(3," TimeWrtSrcTime: " << lTimeWrtSrcTime << " TimeWrtTgtTime: " << lTimeWrtTgtTime ) ;
// //
@ -324,96 +327,23 @@ OutputIterator Polygon_offset_builder_2<Ss,Gt,Cont,Visitor>::construct_offset_co
template<class Ss, class Gt, class Cont, class Visitor> template<class Ss, class Gt, class Cont, class Visitor>
typename Polygon_offset_builder_2<Ss,Gt,Cont,Visitor>::Trisegment_2_ptr typename Polygon_offset_builder_2<Ss,Gt,Cont,Visitor>::Trisegment_2_ptr
Polygon_offset_builder_2<Ss,Gt,Cont,Visitor>::CreateTrisegment ( Vertex_const_handle aNode ) const Polygon_offset_builder_2<Ss,Gt,Cont,Visitor>::GetTrisegment ( Vertex_const_handle aNode ) const
{ {
CGAL_precondition(handle_assigned(aNode)); CGAL_precondition(handle_assigned(aNode));
Trisegment_2_ptr r ; Trisegment_2_ptr r ;
CGAL_POLYOFFSET_TRACE(3,"Creating Trisegment for " << v2str(*aNode) ) ; CGAL_POLYOFFSET_TRACE(3,"Getting Trisegment for " << v2str(*aNode) ) ;
if ( aNode->is_skeleton() ) if ( aNode->is_skeleton() )
{ {
Triedge const& lEventTriedge = aNode->event_triedge() ; r = aNode->trisegment() ;
CGAL_assertion(bool(r));
r = CreateTrisegment(lEventTriedge) ;
CGAL_stskel_intrinsic_test_assertion
(
!CGAL_SS_i::is_possibly_inexact_distance_clearly_not_equal_to( Construct_ss_event_time_and_point_2(mTraits)(r)->get<0>()
, aNode->time()
)
) ;
CGAL_POLYOFFSET_TRACE(3,"Event triedge=" << lEventTriedge ) ;
if ( r->degenerate_seed_id() == Trisegment_2::LEFT )
{
CGAL_POLYOFFSET_TRACE(3,"Left seed is degenerate." ) ;
Vertex_const_handle lLeftSeed = GetSeedVertex(aNode
,aNode->primary_bisector()->prev()->opposite()
,lEventTriedge.e0()
,lEventTriedge.e1()
) ;
if ( handle_assigned(lLeftSeed) )
r->set_child_l( CreateTrisegment(lLeftSeed) ) ; // Recursive call
}
else if ( ! aNode->is_split() && r->degenerate_seed_id() == Trisegment_2::RIGHT )
{
CGAL_POLYOFFSET_TRACE(3,"Right seed is degenerate." ) ;
Vertex_const_handle lRightSeed = GetSeedVertex(aNode
,aNode->primary_bisector()->opposite()->next()
,lEventTriedge.e1()
,lEventTriedge.e2()
) ;
if ( handle_assigned(lRightSeed) )
r->set_child_r( CreateTrisegment(lRightSeed) ) ; // Recursive call
}
} }
return r ; return r ;
} }
template<class Ss, class Gt, class Cont, class Visitor> } // namespace CGAL
typename Polygon_offset_builder_2<Ss,Gt,Cont,Visitor>::Vertex_const_handle
Polygon_offset_builder_2<Ss,Gt,Cont,Visitor>::GetSeedVertex ( Vertex_const_handle aNode
, Halfedge_const_handle aBisector
, Halfedge_const_handle aEa
, Halfedge_const_handle aEb
) const
{
Vertex_const_handle rSeed ;
if ( Is_bisector_defined_by(aBisector,aEa,aEb) ) #endif // CGAL_POLYGON_OFFSET_BUILDER_2_IMPL_H
{
rSeed = aBisector->vertex();
CGAL_POLYOFFSET_TRACE(3,"Seed of N" << aNode->id() << " for vertex (E" << aEa->id() << ",E" << aEb->id() << ") directly found: " << v2str(*rSeed) ) ;
}
else
{
typedef typename Vertex::Halfedge_around_vertex_const_circulator Halfedge_around_vertex_const_circulator ;
Halfedge_around_vertex_const_circulator cb = aNode->halfedge_around_vertex_begin() ;
Halfedge_around_vertex_const_circulator c = cb ;
do
{
Halfedge_const_handle lBisector = *c ;
if ( Is_bisector_defined_by(lBisector,aEa,aEb) )
{
rSeed = lBisector->opposite()->vertex();
CGAL_POLYOFFSET_TRACE(3,"Seed of N" << aNode->id() << " for vertex (E" << aEa->id() << ",E" << aEb->id() << ") indirectly found: V" << rSeed->id() ) ;
}
}
while ( !handle_assigned(rSeed) && ++ c != cb ) ;
}
return rSeed ;
}
} // end namespace CGAL
#endif // CGAL_POLYGON_OFFSET_BUILDER_2_IMPL_H //
// EOF //

View File

@ -30,7 +30,8 @@ namespace CGAL {
namespace CGAL_SS_i { namespace CGAL_SS_i {
template<class K> struct Has_inexact_constructions template<class K>
struct Has_inexact_constructions
{ {
typedef typename K::FT FT ; typedef typename K::FT FT ;
@ -42,6 +43,23 @@ template<class K> struct Has_inexact_constructions
>::type type ; >::type type ;
} ; } ;
template <class K>
struct Segment_2_with_ID
: public K::Segment_2
{
typedef typename K::Segment_2 Base;
typedef typename K::Point_2 Point_2;
public:
Segment_2_with_ID() : Base(), mID(-1) { }
Segment_2_with_ID(Base const& aS) : Base(aS), mID(-1) { }
Segment_2_with_ID(Base const& aS, const std::size_t aID) : Base(aS), mID(aID) { }
Segment_2_with_ID(Point_2 const& aP, Point_2 const& aQ, const std::size_t aID) : Base(aP, aQ), mID(aID) { }
public:
std::size_t mID;
};
// //
// This record encapsulates the defining contour halfedges for a node (both contour and skeleton) // This record encapsulates the defining contour halfedges for a node (both contour and skeleton)
// //
@ -176,10 +194,7 @@ public:
inline void intrusive_ptr_add_ref( Ref_counted_base const* p ) { p->AddRef(); } inline void intrusive_ptr_add_ref( Ref_counted_base const* p ) { p->AddRef(); }
inline void intrusive_ptr_release( Ref_counted_base const* p ) { p->Release(); } inline void intrusive_ptr_release( Ref_counted_base const* p ) { p->Release(); }
} // namespace CGAL } // namespace CGAL
#endif // CGAL_STRAIGHT_SKELETON_AUX_H
#endif // CGAL_STRAIGHT_SKELETON_AUX_H //
// EOF //

View File

@ -113,9 +113,9 @@ Straight_skeleton_builder_2<Gt,Ss,V>::FindEdgeEvent( Vertex_handle aLNode, Verte
if ( GetEdgeEndingAt(lPrevNode) == lTriedge.e2() ) if ( GetEdgeEndingAt(lPrevNode) == lTriedge.e2() )
{ {
// Note that this can be a contour node and in that case GetTrisegment is null and we get // Note that this can be a contour node and in that case GetTrisegment returns null
// the middle point, but in that case e2 and e0 are consecutive in the input // and we get the middle point as a seed, but in that case e2 and e0 are consecutive
// and the middle point is the common extremity and things are fine. // in the input and the middle point is the common extremity thus things are fine.
lTrisegment->set_child_t( GetTrisegment(lPrevNode) ) ; lTrisegment->set_child_t( GetTrisegment(lPrevNode) ) ;
} }
else else
@ -581,7 +581,7 @@ void Straight_skeleton_builder_2<Gt,Ss,V>::CreateContourBisectors()
Vertex_handle lInfNode = mSSkel->SSkel::Base::vertices_push_back( Vertex( mVertexID++ ) ) ; Vertex_handle lInfNode = mSSkel->SSkel::Base::vertices_push_back( Vertex( mVertexID++ ) ) ;
InitVertexData(lInfNode); InitVertexData(lInfNode);
CGAL_assertion(lInfNode->has_null_point()); CGAL_assertion(lInfNode->has_infinite_time());
lRBisector->HBase_base::set_next( lLBisector ); lRBisector->HBase_base::set_next( lLBisector );
lLBisector->HBase_base::set_prev( lRBisector ); lLBisector->HBase_base::set_prev( lRBisector );
@ -1045,10 +1045,7 @@ void Straight_skeleton_builder_2<Gt,Ss,V>::HandleEdgeEvent( EventPtr aEvent )
Halfedge_handle lDefiningBorderB = lNewNode->halfedge()->opposite()->prev()->opposite()->defining_contour_edge(); Halfedge_handle lDefiningBorderB = lNewNode->halfedge()->opposite()->prev()->opposite()->defining_contour_edge();
Halfedge_handle lDefiningBorderC = lNewNode->halfedge()->opposite()->prev()->defining_contour_edge(); Halfedge_handle lDefiningBorderC = lNewNode->halfedge()->opposite()->prev()->defining_contour_edge();
lNewNode->VBase::set_event_triedge( lEvent.triedge() ) ;
Triedge lTri(lDefiningBorderA,lDefiningBorderB,lDefiningBorderC); Triedge lTri(lDefiningBorderA,lDefiningBorderB,lDefiningBorderC);
SetVertexTriedge( lNewNode, lTri ) ; SetVertexTriedge( lNewNode, lTri ) ;
SetBisectorSlope(lLSeed,lNewNode); SetBisectorSlope(lLSeed,lNewNode);
@ -1212,7 +1209,7 @@ void Straight_skeleton_builder_2<Gt,Ss,V>::HandleSplitEvent( EventPtr aEvent, Ve
Vertex_handle lNewFicNode = mSSkel->SSkel::Base::vertices_push_back( Vertex( mVertexID++ ) ) ; Vertex_handle lNewFicNode = mSSkel->SSkel::Base::vertices_push_back( Vertex( mVertexID++ ) ) ;
InitVertexData(lNewFicNode); InitVertexData(lNewFicNode);
CGAL_assertion(lNewFicNode->has_null_point()); CGAL_assertion(lNewFicNode->has_infinite_time());
CrossLink(lNOBisector_R,lNewFicNode); CrossLink(lNOBisector_R,lNewFicNode);
SetBisectorSlope(lNOBisector_L,POSITIVE); SetBisectorSlope(lNOBisector_L,POSITIVE);
@ -1229,9 +1226,6 @@ void Straight_skeleton_builder_2<Gt,Ss,V>::HandleSplitEvent( EventPtr aEvent, Ve
Halfedge_handle lNewNode_R_DefiningBorderB = lNewNode_R->halfedge()->opposite()->prev()->opposite()->defining_contour_edge(); Halfedge_handle lNewNode_R_DefiningBorderB = lNewNode_R->halfedge()->opposite()->prev()->opposite()->defining_contour_edge();
Halfedge_handle lNewNode_R_DefiningBorderC = lNewNode_R->halfedge()->opposite()->prev()->defining_contour_edge(); Halfedge_handle lNewNode_R_DefiningBorderC = lNewNode_R->halfedge()->opposite()->prev()->defining_contour_edge();
lNewNode_L->VBase::set_event_triedge( lEvent.triedge() ) ;
lNewNode_R->VBase::set_event_triedge( lEvent.triedge() ) ;
Triedge lTriL( lNewNode_L_DefiningBorderA,lNewNode_L_DefiningBorderB,lNewNode_L_DefiningBorderC ) ; Triedge lTriL( lNewNode_L_DefiningBorderA,lNewNode_L_DefiningBorderB,lNewNode_L_DefiningBorderC ) ;
Triedge lTriR( lNewNode_R_DefiningBorderA,lNewNode_R_DefiningBorderB,lNewNode_R_DefiningBorderC ) ; Triedge lTriR( lNewNode_R_DefiningBorderA,lNewNode_R_DefiningBorderB,lNewNode_R_DefiningBorderC ) ;
@ -1457,9 +1451,6 @@ void Straight_skeleton_builder_2<Gt,Ss,V>::HandlePseudoSplitEvent( EventPtr aEve
Halfedge_handle lNewNode_R_DefiningBorderB = lNewNode_R->halfedge()->next()->opposite()->defining_contour_edge(); Halfedge_handle lNewNode_R_DefiningBorderB = lNewNode_R->halfedge()->next()->opposite()->defining_contour_edge();
Halfedge_handle lNewNode_R_DefiningBorderC = lNewNode_R->halfedge()->opposite()->prev()->defining_contour_edge(); Halfedge_handle lNewNode_R_DefiningBorderC = lNewNode_R->halfedge()->opposite()->prev()->defining_contour_edge();
lNewNode_L->VBase::set_event_triedge( lEvent.triedge() ) ;
lNewNode_R->VBase::set_event_triedge( lEvent.triedge() ) ;
Triedge lTriL( lNewNode_L_DefiningBorderA, lNewNode_L_DefiningBorderB, lNewNode_L_DefiningBorderC ) ; Triedge lTriL( lNewNode_L_DefiningBorderA, lNewNode_L_DefiningBorderB, lNewNode_L_DefiningBorderC ) ;
Triedge lTriR( lNewNode_R_DefiningBorderA, lNewNode_R_DefiningBorderB, lNewNode_R_DefiningBorderC ) ; Triedge lTriR( lNewNode_R_DefiningBorderA, lNewNode_R_DefiningBorderB, lNewNode_R_DefiningBorderC ) ;

View File

@ -190,23 +190,6 @@ class Rational
NT mN, mD ; NT mN, mD ;
} ; } ;
template <class K>
struct Segment_2_with_ID
: public Segment_2<K>
{
typedef Segment_2<K> Base;
typedef typename K::Point_2 Point_2;
public:
Segment_2_with_ID() : Base(), mID(-1) { }
Segment_2_with_ID(Base const& aS) : Base(aS), mID(-1) { }
Segment_2_with_ID(Base const& aS, const std::size_t aID) : Base(aS), mID(aID) { }
Segment_2_with_ID(Point_2 const& aP, Point_2 const& aQ, const std::size_t aID) : Base(aP, aQ), mID(aID) { }
public:
std::size_t mID;
};
template <class Info> template <class Info>
struct No_cache struct No_cache
{ {

View File

@ -187,8 +187,8 @@ inline std::string e2str( E const& e )
ss << "B" << e.id() ss << "B" << e.id()
<< "[E" << e.defining_contour_edge()->id() << "[E" << e.defining_contour_edge()->id()
<< ",E" << e.opposite()->defining_contour_edge()->id() << "]" << ",E" << e.opposite()->defining_contour_edge()->id() << "]"
<< " (/" << ( e.slope() == CGAL::ZERO ? "·" : ( e.slope() == CGAL::NEGATIVE ? "-" : "+" ) ) << " (S " << ( e.slope() == CGAL::ZERO ? "0" : ( e.slope() == CGAL::NEGATIVE ? "-" : "+" ) )
<< " " << e.opposite()->vertex()->time() << "->" << e.vertex()->time() << ")" ; << "; T " << e.opposite()->vertex()->time() << " -> " << e.vertex()->time() << ")" ;
} }
else else
{ {
@ -263,7 +263,7 @@ inline std::string newn2str( char const* name, VH const& v, Triedge const& aTrie
#endif #endif
#ifdef CGAL_STRAIGHT_SKELETON_TRAITS_ENABLE_TRACE #ifdef CGAL_STRAIGHT_SKELETON_TRAITS_ENABLE_TRACE
bool sEnableTraitsTrace = false; bool sEnableTraitsTrace = true;
# define CGAL_STSKEL_TRAITS_ENABLE_TRACE sEnableTraitsTrace = true ; # define CGAL_STSKEL_TRAITS_ENABLE_TRACE sEnableTraitsTrace = true ;
# define CGAL_STSKEL_TRAITS_ENABLE_TRACE_IF(cond) if ((cond)) sEnableTraitsTrace = true ; # define CGAL_STSKEL_TRAITS_ENABLE_TRACE_IF(cond) if ((cond)) sEnableTraitsTrace = true ;
# define CGAL_STSKEL_TRAITS_DISABLE_TRACE sEnableTraitsTrace = false; # define CGAL_STSKEL_TRAITS_DISABLE_TRACE sEnableTraitsTrace = false;

View File

@ -633,7 +633,10 @@ private :
void SetTrisegment ( Vertex_handle aV, Trisegment_2_ptr const& aTrisegment ) void SetTrisegment ( Vertex_handle aV, Trisegment_2_ptr const& aTrisegment )
{ {
// @todo could get rid of the 'mTrisegment' in vertex data
// since it's also stored in the vertex directly (to be used during offset construction...)
GetVertexData(aV).mTrisegment = aTrisegment ; GetVertexData(aV).mTrisegment = aTrisegment ;
aV->set_trisegment(aTrisegment) ;
} }
// Null if aV is a contour node // Null if aV is a contour node

View File

@ -13,12 +13,14 @@
#include <CGAL/license/Straight_skeleton_2.h> #include <CGAL/license/Straight_skeleton_2.h>
#include <CGAL/Straight_skeleton_2.h> #include <CGAL/Straight_skeleton_2/Straight_skeleton_aux.h>
#include <CGAL/Trisegment_2.h>
#include <CGAL/assertions.h> #include <CGAL/assertions.h>
#include <CGAL/Cartesian_converter.h> #include <CGAL/Cartesian_converter.h>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/intrusive_ptr.hpp>
#include <vector> #include <vector>
@ -41,6 +43,22 @@ struct Straight_skeleton_items_converter_2: Cartesian_converter< typename Source
typedef typename Source_skeleton::Traits Source_traits ; typedef typename Source_skeleton::Traits Source_traits ;
typedef typename Target_skeleton::Traits Target_traits ; typedef typename Target_skeleton::Traits Target_traits ;
typedef CGAL_SS_i::Segment_2_with_ID<Source_traits> Source_segment_2_with_ID;
typedef CGAL_SS_i::Segment_2_with_ID<Target_traits> Target_segment_2_with_ID;
typedef typename Source_traits::Segment_2 Source_segment_2;
typedef typename Target_traits::Segment_2 Target_segment_2;
typedef Trisegment_2<Source_traits, Source_segment_2> Source_trisegment_2;
typedef Trisegment_2<Target_traits, Target_segment_2> Target_trisegment_2;
typedef boost::intrusive_ptr<Source_trisegment_2> Source_trisegment_2_ptr;
typedef boost::intrusive_ptr<Target_trisegment_2> Target_trisegment_2_ptr;
// Same as above, but for Segment with IDs...
typedef Trisegment_2<Source_traits, Source_segment_2_with_ID> Source_trisegment_2_with_ID;
typedef Trisegment_2<Target_traits, Target_segment_2_with_ID> Target_trisegment_2_with_ID;
typedef boost::intrusive_ptr<Source_trisegment_2_with_ID> Source_trisegment_2_with_ID_ptr;
typedef boost::intrusive_ptr<Target_trisegment_2_with_ID> Target_trisegment_2_with_ID_ptr;
typedef Cartesian_converter<Source_traits,Target_traits> Base ; typedef Cartesian_converter<Source_traits,Target_traits> Base ;
typedef typename Source_skeleton::Vertex_const_handle Source_vertex_const_handle ; typedef typename Source_skeleton::Vertex_const_handle Source_vertex_const_handle ;
@ -76,6 +94,63 @@ struct Straight_skeleton_items_converter_2: Cartesian_converter< typename Source
return Target_face( aF->id() ); return Target_face( aF->id() );
} }
Target_segment_2_with_ID operator() ( const Source_segment_2_with_ID& aS ) const
{
return Target_segment_2_with_ID(this->Base::operator()(
static_cast<const typename Source_segment_2_with_ID::Base&>(aS)), aS.mID);
}
Target_trisegment_2_ptr operator() ( const Source_trisegment_2_ptr& aT ) const
{
const auto& lSe0 = aT->e0();
const auto& lSe1 = aT->e1();
const auto& lSe2 = aT->e2();
Trisegment_collinearity lCollinearity = aT->collinearity();
std::size_t lId = aT->id();
Target_trisegment_2_ptr rT = Target_trisegment_2_ptr(
new Target_trisegment_2(this->operator()(lSe0),
this->operator()(lSe1),
this->operator()(lSe2),
lCollinearity, lId));
if ( aT->child_l() )
rT->set_child_l(this->operator()(aT->child_l()));
if ( aT->child_r() )
rT->set_child_r(this->operator()(aT->child_r()));
if ( aT->child_t() )
rT->set_child_t(this->operator()(aT->child_t()));
return rT;
}
Target_trisegment_2_with_ID_ptr operator() ( const Source_trisegment_2_with_ID_ptr& aT ) const
{
const auto& lSe0 = aT->e0();
const auto& lSe1 = aT->e1();
const auto& lSe2 = aT->e2();
Trisegment_collinearity lCollinearity = aT->collinearity();
std::size_t lId = aT->id();
Target_trisegment_2_with_ID_ptr rT = Target_trisegment_2_with_ID_ptr(
new Target_trisegment_2_with_ID(this->operator()(lSe0),
this->operator()(lSe1),
this->operator()(lSe2),
lCollinearity, lId));
if ( aT->child_l() )
rT->set_child_l(this->operator()(aT->child_l()));
if ( aT->child_r() )
rT->set_child_r(this->operator()(aT->child_r()));
if ( aT->child_t() )
rT->set_child_t(this->operator()(aT->child_t()));
return rT;
}
} ; } ;
template<class Source_skeleton_, class Target_skeleton_, class Items_converter_> template<class Source_skeleton_, class Target_skeleton_, class Items_converter_>
@ -201,20 +276,8 @@ private :
CGAL_assertion( handle_assigned(tgt_halfedge) ) ; CGAL_assertion( handle_assigned(tgt_halfedge) ) ;
tvit->VBase::set_halfedge(tgt_halfedge); tvit->VBase::set_halfedge(tgt_halfedge);
Target_halfedge_handle tgt_striedge_e0, tgt_striedge_e1, tgt_striedge_e2 ; if(svit->trisegment()) // contour nodes do not have trisegments
tvit->set_trisegment(cvt(svit->trisegment()));
Source_triedge const& stri = svit->event_triedge() ;
if ( handle_assigned(stri.e0()) )
tgt_striedge_e0 = Target_halfedges.at(stri.e0()->id());
if ( handle_assigned(stri.e1()) )
tgt_striedge_e1 = Target_halfedges.at(stri.e1()->id());
if ( handle_assigned(stri.e2()) )
tgt_striedge_e2 = Target_halfedges.at(stri.e2()->id());
tvit->VBase::set_event_triedge( Target_triedge(tgt_striedge_e0, tgt_striedge_e1, tgt_striedge_e2) ) ;
} }
Target_halfedge_iterator thit = aTarget.halfedges_begin(); Target_halfedge_iterator thit = aTarget.halfedges_begin();

View File

@ -62,8 +62,6 @@ public:
return !this->vertex()->is_contour() && !this->opposite()->vertex()->is_contour(); return !this->vertex()->is_contour() && !this->opposite()->vertex()->is_contour();
} }
bool has_null_segment() const { return this->vertex()->has_null_point() ; }
bool has_infinite_time() const { return this->vertex()->has_infinite_time() ; } bool has_infinite_time() const { return this->vertex()->has_infinite_time() ; }
Halfedge_const_handle defining_contour_edge() const { return this->face()->halfedge() ; } Halfedge_const_handle defining_contour_edge() const { return this->face()->halfedge() ; }

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