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:
pull_request_target:
types: [synchronize]
workflow_dispatch:
jobs:
remove_label:
runs-on: ubuntu-latest

View File

@ -3,6 +3,7 @@ name: Documentation
on:
issue_comment:
types: [created]
workflow_dispatch:
permissions:
contents: read # to fetch code (actions/checkout)
@ -47,7 +48,7 @@ jobs:
//get pullrequest url
const pr_number = context.payload.issue.number
return pr_number
- name: Emoji-comment
uses: actions/github-script@v6
if: steps.get_round.outputs.result != 'stop'
@ -59,7 +60,7 @@ jobs:
repo: context.repo.repo,
content: 'rocket'
})
- uses: actions/checkout@v3
name: "checkout branch"
if: steps.get_round.outputs.result != 'stop'
@ -74,7 +75,7 @@ jobs:
run: |
set -x
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
wget --no-verbose -O doxygen_exe https://cgal.geometryfactory.com/~cgaltest/doxygen_1_8_13_patched/doxygen
sudo mv doxygen_exe /usr/bin/doxygen

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -153,14 +153,19 @@ public:
Dag_node* m_dag_node; //pointer to the search structure (DAG) node
/*! Initialize the trapezoid's neighbors. */
CGAL_TD_INLINE void init_neighbours(Self* lb_ = 0, Self* lt_ = 0,
Self* rb_ = 0, Self* rt_ = 0)
CGAL_TD_INLINE void init_neighbors(Self* lb_ = 0, Self* lt_ = 0,
Self* rb_ = 0, Self* rt_ = 0)
{
set_lb(lb_);
set_lt(lt_);
set_rb(rb_);
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. */
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
/*! 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));
}
/*! \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. */
CGAL_TD_INLINE void set_dag_node(Dag_node* p)

View File

@ -163,14 +163,19 @@ private:
//Dag_node* m_dag_node; //pointer to the search structure (DAG) node
/*! Initialize the trapezoid's neighbors. */
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)
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)
{
set_lb((lb) ? *lb : Td_map_item(0));
set_lt((lt) ? *lt : Td_map_item(0));
set_rb((rb) ? *rb : 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. */
inline void set_dag_node(Dag_node* p)

View File

@ -72,10 +72,10 @@ split_trapezoid_by_vertex(Dag_node& split_node,
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());
left_tr.init_neighbours(tr.lb(), tr.lt(),
right_node.get_data(), right_node.get_data());
right_tr.init_neighbours(left_node.get_data(), left_node.get_data(),
tr.rb(), tr.rt());
left_tr.init_neighbors(tr.lb(), tr.lt(),
right_node.get_data(), right_node.get_data());
right_tr.init_neighbors(left_node.get_data(), left_node.get_data(),
tr.rb(), tr.rt());
if (!traits->is_empty_item(tr.lb())) {
Td_active_trapezoid& lb(boost::get<Td_active_trapezoid>(tr.lb()));
lb.set_rb(left_node.get_data());
@ -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(right_e.is_on_right_boundary() == e.is_on_right_boundary());
left_e.init_neighbours(boost::none);
//left_e.init_neighbours(e.lb(),e.lt(),Td_map_item(),right_node.get_data());
right_e.init_neighbours(e.next());
//right_e.init_neighbours(left_node.get_data(),left_node.get_data(),e.rb(),e.rt());
left_e.init_neighbors(boost::none);
//left_e.init_neighbors(e.lb(),e.lt(),Td_map_item(),right_node.get_data());
right_e.init_neighbors(e.next());
//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,
@ -307,8 +307,8 @@ split_trapezoid_by_halfedge(Dag_node& split_node,
Td_active_trapezoid& top =
boost::get<Td_active_trapezoid>(top_node.get_data());
top.init_neighbours(prev_top_tr, split_tr.lt(), boost::none , split_tr.rt());
bottom.init_neighbours(split_tr.lb(), prev_bottom_tr, split_tr.rb(),
top.init_neighbors(prev_top_tr, split_tr.lt(), boost::none , split_tr.rt());
bottom.init_neighbors(split_tr.lb(), prev_bottom_tr, split_tr.rb(),
boost::none);
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
// {
// //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.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
// {
// //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.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)
ready = true;
if(!test_neighbourhood(pix, back_dir, new_dir)) {
if(!test_neighborhood(pix, back_dir, new_dir)) {
ux = pix.x;
uy = pix.y;
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;
}
if(!test_neighbourhood(pix, back_dir, new_dir)) {
if(!test_neighborhood(pix, back_dir, new_dir)) {
if(stored_dir != -1) {
pix = stored_pix;
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);
//Gfx_DETAILED_OUT("subpixel index: " << idx << " (" << pix.sub_x << "; "
// << 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);
//Gfx_DETAILED_OUT("new direction found: " << new_dir << " at a pixel:" <<
//pix << std::endl);
@ -1313,7 +1313,7 @@ bool get_seed_point(const Rational& seed, Pixel_2& start, int *dir,
<< start.level << std::endl;
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))) {
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");
dump_neighbourhood(pix);
dump_neighborhood(pix);
Gfx_OUT("----------------------------------------------\n\n");*/
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
* 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 inv = NT(1.0) / lvl;
@ -2258,6 +2258,11 @@ Lexit:
pix.yv = CGAL::to_double(engine.y_min + y*engine.pixel_h);
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
//! \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
#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::cout, CGAL::IO::PRETTY);
@ -2764,8 +2769,10 @@ void dump_neighbourhood(const Pixel_2& pix) {
Gfx_OUT("sign change at segment 2" << std::endl);
}
#else
void dump_neighbourhood(const Pixel_2&) { }
void dump_neighborhood(const Pixel_2&) { }
#endif // Gfx_USE_OUT
CGAL_DEPRECATED void dump_neighbourhood(const Pixel_2& pix)
{ dump_neighborhood(pix); }
//!@}
}; // class Curve_renderer_2<>

View File

@ -1,4 +1,4 @@
@INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS}
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
*/

View File

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

View File

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

View File

@ -128,7 +128,7 @@ int main (int argc, char** argv)
}
// Write result
std::ofstream f ("classification.ply");
std::ofstream f ("classification_opencv_random_forest.ply");
f.precision(18);
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)
for (Mesh::Halfedge_index hi : holes)
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
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;
// 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);
classified_ofile << points;
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
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 */

View File

@ -6,4 +6,5 @@
\example Convex_hull_2/ch_timing.cpp
\example Convex_hull_2/iostream_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);
#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;
}

View File

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

View File

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

View File

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

View File

@ -26,7 +26,7 @@ else()
set(CGAL_ROOT "${CMAKE_SOURCE_DIR}")
endif()
find_package(Doxygen)
find_package(Doxygen REQUIRED)
find_package(Python3 REQUIRED COMPONENTS Interpreter)
if (NOT Python3_EXECUTABLE)
@ -138,6 +138,10 @@ function(configure_doxygen_package CGAL_PACKAGE_NAME)
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
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:
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:
C:\dev\vcpkg> ./vcpkg.exe install cgal
C:\dev\vcpkg> .\vcpkg.exe install cgal
This will take several minutes as it downloads \gmp,
\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
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.
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*:
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,
the CMake variables and paths concerning Qt should now be filled.

View File

@ -32,6 +32,17 @@
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
,author = {Avnaim, F.}
,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('<html xmlns=\"https://www.w3.org/1999/xhtml\">')
if d.html() is not None:
f.write(d.html())
f.write(d.html(method='html'))
f.write('\n')
f.write('</html>\n')
f.close()

View File

@ -1,3 +1,3 @@
#!/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
:go
${PYTHON_EXECUTABLE} ${CMAKE_BINARY_DIR}/pkglist_filter.py %1
${Python3_EXECUTABLE} ${CMAKE_BINARY_DIR}/pkglist_filter.py %1
@echo on

View File

@ -555,87 +555,32 @@ MainWindow::loadWKT(QString filename)
{
//Polygons todo : make it multipolygons
std::ifstream ifs(qPrintable(filename));
do
{
typedef CGAL::Polygon_with_holes_2<K> Polygon;
typedef CGAL::Point_2<K> Point;
std::vector<Polygon> mps;
CGAL::IO::read_multi_polygon_WKT(ifs, mps);
for(const Polygon& p : mps)
{
if(p.outer_boundary().is_empty())
continue;
for(Point point : p.outer_boundary().container())
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());
typedef CGAL::Polygon_with_holes_2<K> Polygon;
typedef CGAL::Point_2<K> Point;
for(Polygon::Hole_const_iterator h_it =
p.holes_begin(); h_it != p.holes_end(); ++h_it)
{
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());
std::deque<Point> points;
std::deque<std::vector<Point>> linestrings;
std::deque<Polygon> polygons;
//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);
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())
continue;
cdt.insert_constraint(p.outer_boundary().vertices_begin(), p.outer_boundary().vertices_end(),true);
for(Polygon::Hole_const_iterator h_it = p.holes_begin(); h_it != p.holes_end(); ++h_it){
cdt.insert_constraint(h_it->vertices_begin(), h_it->vertices_end(),true);
}
}while(ifs.good() && !ifs.eof());
}
discoverComponents(cdt, m_seeds);
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.
- 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)
-----------

View File

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

View File

@ -237,8 +237,8 @@ public:
const auto ires12 = CGAL::intersection(o1, o2);
Res tmp;
if(has_exact_p)
Res tmp;
if(has_exact_c)
{
assert(CGAL::assign(tmp, ires12));
assert(approx_equal(tmp, result));
@ -246,7 +246,7 @@ public:
else
{
if(CGAL::assign(tmp, ires12))
assert(approx_equal(tmp, result));
CGAL_warning(approx_equal(tmp, result));
else
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
//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 * >&all,
VertexPropertyMap& vpm);
@ -58,10 +58,10 @@ protected:
template < class TPoly , class VertexPropertyMap>
void T_PolyhedralSurf_rings <TPoly, VertexPropertyMap>::
push_neighbours_of(Vertex * start, int ith,
std::vector < Vertex * >&nextRing,
std::vector < Vertex * >&all,
VertexPropertyMap& vpm)
push_neighbors_of(Vertex * start, int ith,
std::vector < Vertex * >&nextRing,
std::vector < Vertex * >&all,
VertexPropertyMap& vpm)
{
Vertex *v;
Halfedge_around_vertex_circulator
@ -88,7 +88,7 @@ collect_ith_ring(int ith, std::vector < Vertex * >&currentRing,
typename std::vector < Vertex * >::iterator
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>

View File

@ -14,6 +14,7 @@
#define CGAL_PROJECTION_TRAITS_XY_3_H
#include <CGAL/Kernel_23/internal/Projection_traits_3.h>
#include <CGAL/Triangulation_structural_filtering_traits.h>
namespace CGAL {
@ -22,6 +23,11 @@ class Projection_traits_xy_3
: 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
#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( dir.transform(gat3).transform(gat2) == dir.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;
assert( vec.transform(gat1) == vec.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) );
co1 = gat1 * gat1.inverse() ;
assert( vec == vec.transform(co1) );
assert( pnt == pnt.transform(co1) );
assert( pnt == pnt.transform(co1) || nonexact);
assert( dir == dir.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>(2,1)));
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
@ -642,7 +642,7 @@ _test_cls_aff_transformation_2(const R& )
assert(p1 == p.transform(comp1));
p1 = p.transform(refl);
p1 = p1.transform(scal);
assert(p1 == p.transform(comp2));
assert(p1 == p.transform(comp2) || nonexact);
//with rotation
CGAL::Aff_transformation_2<R> rot(CGAL::ROTATION, 1, 0);
comp1 = refl*rot;
@ -652,7 +652,7 @@ _test_cls_aff_transformation_2(const R& )
assert(p1 == p.transform(comp1));
p1 = p.transform(refl);
p1 = p1.transform(rot);
assert(p1 == p.transform(comp2));
assert(p1 == p.transform(comp2) || nonexact);
//with reflection
CGAL::Aff_transformation_2<R> refl2(CGAL::REFLECTION, CGAL::Line_2<R>(
CGAL::Point_2<R>(0,0),
@ -664,7 +664,7 @@ _test_cls_aff_transformation_2(const R& )
assert(p1 == p.transform(comp1));
p1 = p.transform(refl);
p1 = p1.transform(refl2);
assert(p1 == p.transform(comp2));
assert(p1 == p.transform(comp2) || nonexact);
//with transformation
CGAL::Aff_transformation_2<R> afft(1,2,3,4,5,6);
comp1 = refl*afft;
@ -674,7 +674,7 @@ _test_cls_aff_transformation_2(const R& )
assert(p1 == p.transform(comp1));
p1 = p.transform(refl);
p1 = p1.transform(afft);
assert(p1 == p.transform(comp2));
assert(p1 == p.transform(comp2) || nonexact);
//equality
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 == c7 );
assert( c5.center() == p3 );
assert( c5.center() == p3 || nonexact);
assert( cc.center() == p3 );
assert( c5.squared_radius() == FT( n9 ) );
assert( c4.squared_radius() == cc.squared_radius() );
assert( c4 == c5 );
assert( c4 == c5 || nonexact);
assert( c4 == c7 );
assert( c4 != c8 );
assert( cn == cp.opposite() );
@ -114,7 +114,7 @@ _test_cls_sphere_3(const R& )
std::cout << '.';
assert( c4.center() == p3 );
assert( c5.center() == p3 );
assert( c5.center() == p3 || nonexact);
assert( c4.squared_radius() == FT( n9 ) );
assert( c5.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 );
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);
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);
Plane_3 pl3( p4, p5, p6);
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 );
Plane_3 pl4( p4, p6, p5);
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 );
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>
{
public:
#ifdef DOXYGEN_RUNNING
typedef unspecified_type Triangulation_data_structure;
#else
typedef internal::Dummy_tds_3 Triangulation_data_structure;
#endif
typedef Triangulation_data_structure::Vertex_handle Vertex_handle;
typedef Triangulation_data_structure::Cell_handle Cell_handle;
template <typename TDS2>
@ -761,7 +765,11 @@ template <typename GT,
class Compact_mesh_cell_generator_3
{
public:
#ifdef DOXYGEN_RUNNING
typedef unspecified_type Triangulation_data_structure;
#else
typedef internal::Dummy_tds_3 Triangulation_data_structure;
#endif
typedef Triangulation_data_structure::Vertex_handle Vertex_handle;
typedef Triangulation_data_structure::Cell_handle Cell_handle;
template <typename TDS2>

View File

@ -690,7 +690,8 @@ initialize()
# ifdef CGAL_CONCURRENT_MESH_3_VERBOSE
std::cerr << "Adding points on a far sphere (radius = " << radius <<")...";
# 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>(
float(std::thread::hardware_concurrency())
* 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
= domain.is_in_domain_object()(seed_point);
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
: domain.is_in_domain_object()(
seed_cell->weighted_circumcenter(tr.geom_traits()));

View File

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

View File

@ -317,7 +317,11 @@ template<class GT,
class MD,
class Vb = Regular_triangulation_vertex_base_3<GT> >
struct Mesh_vertex_base_3 {
#ifdef DOXYGEN_RUNNING
using Triangulation_data_structure = unspecified_type;
#else
using Triangulation_data_structure = internal::Dummy_tds_3;
#endif
using Vertex_handle = typename Triangulation_data_structure::Vertex_handle;
using Cell_handle = typename Triangulation_data_structure::Cell_handle;
@ -335,7 +339,11 @@ template<class GT,
class Index,
class Vb = Regular_triangulation_vertex_base_3<GT> >
struct Mesh_vertex_generator_3 {
#ifdef DOXYGEN_RUNNING
using Triangulation_data_structure = unspecified_type;
#else
using Triangulation_data_structure = internal::Dummy_tds_3;
#endif
using Vertex_handle = typename Triangulation_data_structure::Vertex_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_with_default_edge_size.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_polyhedral_domain_with_features_deprecated.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_with_default_edge_size
test_meshing_determinism
test_meshing_without_features_determinism
test_mesh_3_issue_1554
test_mesh_polyhedral_domain_with_features_deprecated
test_mesh_cell_base_3
@ -97,6 +99,8 @@ if ( CGAL_FOUND )
test_meshing_polyhedron
test_meshing_polyhedral_complex
test_mesh_capsule_var_distance_bound
test_meshing_determinism
test_meshing_without_features_determinism
test_mesh_3_issue_1554
test_mesh_polyhedral_domain_with_features_deprecated
test_mesh_cell_base_3

View File

@ -68,7 +68,10 @@ void test()
// iterate
std::vector<std::string> output_c3t3;
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)
{
std::cout << "------- Iteration " << (i+1) << " -------" << std::endl;
@ -133,14 +136,16 @@ void test()
if(i == 0)
continue;
//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";
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";
assert(false);
@ -151,8 +156,11 @@ void test()
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

@ -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
// Minkowski Sums via Convolution: Theory and Practice" at Tel-Aviv University.
template <typename Kernel_, typename Container_>
class Minkowski_sum_by_reduced_convolution_2
{
class Minkowski_sum_by_reduced_convolution_2 {
private:
typedef Kernel_ Kernel;
typedef Container_ Container;
@ -56,14 +55,14 @@ private:
// Arrangement-related types:
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::Face_iterator Face_iterator;
typedef typename Arrangement_history_2::Face_handle Face_handle;
typedef typename Arrangement_history_2::Ccb_halfedge_circulator
Ccb_halfedge_circulator;
typedef typename Arrangement_history_2::Originating_curve_iterator
Originating_curve_iterator;
typedef typename Arrangement_history_2::Inner_ccb_iterator Inner_ccb_iterator;
typedef typename Arrangement_history_2::Halfedge_const_handle
Halfedge_const_handle;
typedef typename Arrangement_history_2::Face_const_handle
Face_const_handle;
typedef typename Arrangement_history_2::Ccb_halfedge_const_circulator
Ccb_halfedge_const_circulator;
typedef typename Arrangement_history_2::Inner_ccb_const_iterator
Inner_ccb_const_iterator;
// Function object types:
typename Kernel::Construct_translated_point_2 f_add;
@ -74,8 +73,8 @@ private:
typename Kernel::Counterclockwise_in_between_2 f_ccw_in_between;
public:
Minkowski_sum_by_reduced_convolution_2()
{
//! \brief constructs.
Minkowski_sum_by_reduced_convolution_2() {
// Obtain kernel functors
Kernel ker;
f_add = ker.construct_translated_point_2_object();
@ -86,10 +85,10 @@ public:
f_ccw_in_between = ker.counterclockwise_in_between_2_object();
}
//! \brief applies the Minkowski sum reduced-convolution operator.
template <typename OutputIterator>
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(pgn2.is_simple());
CGAL_precondition(pgn1.orientation() == COUNTERCLOCKWISE);
@ -101,19 +100,17 @@ public:
common_operator(pwh1, pwh2, outer_boundary, holes);
}
//! \brief applies the Minkowski sum reduced-convolution operator.
template <typename OutputIterator>
void operator()(const Polygon_with_holes_2& pgn1,
const Polygon_with_holes_2& pgn2,
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>
void operator()(const Polygon_2& pgn1,
const Polygon_with_holes_2& pgn2,
Polygon_2& outer_boundary, OutputIterator holes) const
{
void operator()(const Polygon_2& pgn1, const Polygon_with_holes_2& pgn2,
Polygon_2& outer_boundary, OutputIterator holes) const {
CGAL_precondition(pgn1.is_simple());
CGAL_precondition(pgn1.orientation() == COUNTERCLOCKWISE);
const Polygon_with_holes_2 pwh1(pgn1);
@ -121,11 +118,11 @@ public:
}
private:
//! \brief applies the Minkowski sum reduced-convolution operator.
template <typename OutputIterator>
void common_operator(const Polygon_with_holes_2& pgn1,
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
// the entire plane.
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
// 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.
// The unbounded face cannot contribute to the Minkowski sum
@ -169,8 +166,8 @@ private:
// The face needs to be orientable
if (! test_face_orientation(arr, fit)) continue;
// When the reversed polygon 1, translated by a point inside of this face,
// collides with polygon 2, this cannot be a hole
// When the reversed polygon 1, translated by a point inside of this
// face, collides with polygon 2, this cannot be a hole
Point_2 inner_point = get_point_in_face(fit);
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
// polygons-with-holes.
/*! \brief builds the reduced convolution for each pair of loops in the two
* polygons-with-holes.
*/
void build_reduced_convolution(const Polygon_with_holes_2& pgnwh1,
const Polygon_with_holes_2& pgnwh2,
Segment_list& reduced_convolution) const
{
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;
}
Polygon_2 pgn1, pgn2;
Segment_list& reduced_convolution) const {
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;
if (x == 0) {
pgn1 = pgnwh1.outer_boundary();
const auto& pgn1 = pgnwh1.outer_boundary();
if (y == 0) {
const auto& pgn2 = pgnwh2.outer_boundary();
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 {
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;
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);
}
}
if (y == 0) {
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);
}
}
}
// Builds the reduced convolution using a fiber grid approach. For 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
// iteration beginning from each vertex in the first column of the fiber
// grid.
/*! \brief builds the reduced convolution using a fiber grid approach. For
* 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
* iteration beginning from each vertex in the first column of the fiber
* grid.
*/
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 n2 = static_cast<int>(pgn2.size());
if ((n1 == 0) || (n2 == 0)) return;
@ -244,13 +237,9 @@ private:
// Init the queue with vertices from the first column
std::queue<State> state_queue;
for (int i = n1-1; i >= 0; --i)
{
state_queue.push(State(i, 0));
}
for (int i = n1-1; i >= 0; --i) state_queue.push(State(i, 0));
while (state_queue.size() > 0)
{
while (state_queue.size() > 0) {
State curr_state = state_queue.front();
state_queue.pop();
@ -258,10 +247,7 @@ private:
int i2 = curr_state.second;
// If this state was already visited, skip it
if (visited_states.count(curr_state) > 0)
{
continue;
}
if (visited_states.count(curr_state) > 0) continue;
visited_states.insert(curr_state);
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
// 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;
if (step_in_pgn1)
{
if (step_in_pgn1) {
new_i1 = next_i1;
new_i2 = i2;
}
else
{
else {
new_i1 = i1;
new_i2 = next_i2;
}
@ -289,39 +272,33 @@ private:
// the other polygon's vertex' ingoing and outgoing directions,
// the segment belongs to the full convolution.
bool belongs_to_convolution;
if (step_in_pgn1)
{
if (step_in_pgn1) {
belongs_to_convolution =
f_ccw_in_between(p1_dirs[i1], p2_dirs[prev_i2], p2_dirs[i2]) ||
p1_dirs[i1] == p2_dirs[i2];
}
else
{
else {
belongs_to_convolution =
f_ccw_in_between(p2_dirs[i2], p1_dirs[prev_i1], p1_dirs[i1]) ||
p2_dirs[i2] == p1_dirs[prev_i1];
}
if (belongs_to_convolution)
{
if (belongs_to_convolution) {
state_queue.push(State(new_i1, new_i2));
// Only edges added to convex vertices can be on the M-sum's boundary.
// This filter only leaves the *reduced* convolution.
bool convex;
if (step_in_pgn1)
{
if (step_in_pgn1) {
convex = is_convex(p2_vertices[prev_i2], p2_vertices[i2],
p2_vertices[next_i2]);
}
else
{
else {
convex = is_convex(p1_vertices[prev_i1], p1_vertices[i1],
p1_vertices[next_i1]);
}
if (convex)
{
if (convex) {
Point_2 start_point = get_point(i1, i2, p1_vertices, p2_vertices);
Point_2 end_point = get_point(new_i1, new_i2, p1_vertices,
p2_vertices);
@ -334,27 +311,21 @@ private:
// Returns a vector of the polygon's vertices, in case that Container
// 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;
for (typename Polygon_2::Vertex_const_iterator it = p.vertices_begin();
it != p.vertices_end(); it++)
{
for (auto it = p.vertices_begin(); it != p.vertices_end(); it++)
vertices.push_back(*it);
}
return vertices;
}
// Returns a sorted list of the polygon's edges
std::vector<Direction_2> directions_of_polygon(
const std::vector<Point_2>& points) const
{
std::vector<Direction_2>
directions_of_polygon(const std::vector<Point_2>& points) const {
std::vector<Direction_2> directions;
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[n-1], points[0])));
@ -362,69 +333,59 @@ private:
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,
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,
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'
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());
}
do outer_boundary.push_back(circ->source()->point());
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,
const Face_handle face) const
{
const Face_const_handle face) const {
// The face needs to be orientable
Ccb_halfedge_circulator start = face->outer_ccb();
Ccb_halfedge_circulator circ = start;
Ccb_halfedge_const_circulator start = face->outer_ccb();
Ccb_halfedge_const_circulator circ = start;
do if (!do_original_edges_have_same_direction(arr, circ)) return false;
while (++circ != start);
return true;
}
// Add a face to 'holes'.
//! \brief adds a face to 'holes'.
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;
Ccb_halfedge_circulator start = face->outer_ccb();
Ccb_halfedge_circulator circ = start;
Ccb_halfedge_const_circulator start = face->outer_ccb();
Ccb_halfedge_const_circulator circ = start;
do pgn_hole.push_back(circ->source()->point());
while (--circ != start);
*holes = pgn_hole;
++holes;
}
// Check whether the convolution's original edge(s) had the same direction as
// the arrangement's half edge
/*! \brief checks whether the convolution's original edge(s) had the same
* direction as the arrangement's half edge.
*/
bool do_original_edges_have_same_direction(const Arrangement_history_2& arr,
const Halfedge_handle he) const
{
Originating_curve_iterator segment_itr;
for (segment_itr = arr.originating_curves_begin(he);
Halfedge_const_handle he) const {
for (auto segment_itr = arr.originating_curves_begin(he);
segment_itr != arr.originating_curves_end(he); ++segment_itr)
{
if (f_compare_xy(segment_itr->source(), segment_itr->target()) ==
@ -437,41 +398,34 @@ private:
return true;
}
// Return a point in the face's interior by finding a diagonal
Point_2 get_point_in_face(const Face_handle face) const
{
Ccb_halfedge_circulator current_edge = face->outer_ccb();
Ccb_halfedge_circulator next_edge = current_edge;
next_edge++;
//! \brief obtains a point in the face's interior by finding a diagonal
Point_2 get_point_in_face(Face_const_handle face) const {
Ccb_halfedge_const_circulator next = face->outer_ccb();
Ccb_halfedge_const_circulator curr = next++;
Point_2 a, v, b;
// Move over the face's vertices until a convex corner is encountered:
do
{
a = current_edge->source()->point();
v = current_edge->target()->point();
b = next_edge->target()->point();
current_edge++;
next_edge++;
// Move over the face's vertices until a convex corner is encountered.
// Observe that the outer ccb of a hole is clockwise oriented.
while (! is_convex(curr->source()->point(),
curr->target()->point(),
next->target()->point())) {
curr = next;
++next;
}
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);
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
// distance to v:
while (++next_edge != current_edge)
{
const Point_2& q = next_edge->target()->point();
if (ear.has_on_bounded_side(q))
{
while (++next != curr) {
const Point_2& q = next->target()->point();
if (ear.has_on_bounded_side(q)) {
FT distance = squared_distance(q, v);
if ((min_q == 0) || (distance < min_distance))
{
if ((min_q == 0) || (distance < min_distance)) {
min_distance = distance;
min_q = &q;
}
@ -483,15 +437,14 @@ private:
return (min_q == 0) ? centroid(ear) : midpoint(v, *min_q);
}
//! \brief transforms a polygon with holes.
template <typename Transformation>
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()));
typename Polygon_with_holes_2::Hole_const_iterator it = p.holes_begin();
while (it != p.holes_end())
{
auto it = p.holes_begin();
while (it != p.holes_end()) {
Polygon_2 p2(it->vertices_begin(), it->vertices_end());
result.add_hole(CGAL::transform(t, p2));
++it;

View File

@ -5,7 +5,6 @@ EXTRACT_ALL = false
HIDE_UNDOC_CLASSES = true
WARN_IF_UNDOCUMENTED = true
EXCLUDE = ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Optimal_bounding_box/internal
EXCLUDE_SYMBOLS += experimental
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;
for (it = samples.begin(); it != samples.end(); ++it)
{
Sample_* sample = *it;
Point p = sample->point();
FT m = 0.5*(1.0 - sample->mass());
const Sample_& sample = this->m_samples[* it];
Point p = sample.point();
FT m = 0.5*(1.0 - sample.mass());
Point q;
if (mesh.get_plan(edge) == 0)
@ -188,7 +188,7 @@ void R_s_k_2::draw_edge_footpoints(const Triangulation& mesh,
else
{
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);
}
draw_segment(p, q);
@ -395,8 +395,8 @@ void R_s_k_2::draw_bins_plan0(const Edge& edge)
Sample_vector_const_iterator it;
for (it = samples.begin(); it != samples.end(); ++it)
{
Sample_* sample = *it;
const Point& ps = sample->point();
const Sample_& sample = this->m_samples[* it];
const Point& ps = sample.point();
Point q = 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();
queue.pop();
const FT m = psample.sample()->mass();
const Point& ps = psample.sample()->point();
const FT m = this->m_samples[psample.sample()].mass();
const Point& ps = this->m_samples[psample.sample()].point();
FT bin = m/M;
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);
if (!ok) return;
Triangulation copy;
Triangulation copy(this->m_samples);
Edge copy_edge = copy_star(edge, copy);
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);
if (!ok) return;
Triangulation copy;
Triangulation copy(this->m_samples);
Edge copy_edge = copy_star(edge, copy);
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);
if (!ok) return;
Triangulation copy;
Triangulation copy(this->m_samples);
Edge copy_edge = copy_star(edge, copy);
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);
if (!ok) return;
Triangulation copy;
Triangulation copy(this->m_samples);
Edge copy_edge = copy_star(edge, copy);
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++;
}
Triangulation copy;
Triangulation copy(this->m_samples);
Edge_vector copy_hull;
Edge_vector copy_stencil;
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::Sample_ Sample_;
typedef R_s_2::Sample_vector Sample_vector;
typedef R_s_2::Sample_vector_const_iterator Sample_vector_const_iterator;
typedef std::vector<Sample_> Sample_vector;
typedef Sample_vector::const_iterator Sample_vector_const_iterator;
typedef R_s_2::PSample PSample;
typedef R_s_2::SQueue SQueue;
@ -452,7 +452,7 @@ public:
for (std::vector<Sample_>::iterator it = m_samples.begin();
it != m_samples.end(); ++it) {
Sample_& s = *it;
samples.push_back(&s);
samples.push_back(s);
}
if (filename.contains(".xy", Qt::CaseInsensitive)) {
@ -469,8 +469,8 @@ public:
std::ofstream ofs(qPrintable(filename));
for (Sample_vector_const_iterator it = samples.begin();
it != samples.end(); ++it) {
Sample_* sample = *it;
ofs << sample->point() << std::endl;
const Sample_& sample = *it;
ofs << sample.point() << std::endl;
}
ofs.close();
}
@ -505,12 +505,12 @@ public:
Sample_vector_const_iterator it;
for (it = vertices.begin(); it != vertices.end(); it++) {
vertices_mass_list.push_back(
std::make_pair((*it)->point(), (*it)->mass()));
std::make_pair((*it).point(), (*it).mass()));
}
PointMassList samples_mass_list;
for (it = samples.begin(); it != samples.end(); it++) {
samples_mass_list.push_back(
std::make_pair((*it)->point(), (*it)->mass()));
std::make_pair((*it).point(), (*it).mass()));
}
Point_property_map point_pmap;
@ -551,10 +551,10 @@ public:
for (it = m_samples.begin(); it != m_samples.end(); ++it) {
Sample_& s = *it;
samples.push_back(&s);
samples.push_back(s);
FT rv = random.get_double(0.0, 1.0);
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 ()
{
CGAL::get_default_random() = CGAL::Random(1671586136);
// Generate a set of random points on the boundary of a square.
std::vector<Point> points;
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; }
template <typename SampleContainer>
void set_total_weight(const SampleContainer& samples)
template <typename Samples, typename SampleContainer>
void set_total_weight(const Samples& m_samples, const SampleContainer& samples)
{
m_total_weight = (FT)0;
for (typename SampleContainer::const_iterator it = samples.begin();
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

View File

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

View File

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

View File

@ -37,7 +37,7 @@ class Reconstruction_vertex_base_2 : public Vb
public:
typedef Vb Base;
typedef typename Traits_::FT FT;
typedef OTR_2::Sample<Traits_> Sample_;
typedef OTR_2::Sample<Traits_> Sample_;
typedef typename Traits_::Point_2 Point;
typedef typename Base::Face_handle Face_handle;
@ -50,7 +50,7 @@ public:
private:
int m_id;
bool m_pinned;
Sample_* m_sample;
int m_sample;
Point m_relocated;
FT m_relevance;
@ -60,7 +60,7 @@ public:
: Base(),
m_id(-1),
m_pinned(false),
m_sample(nullptr),
m_sample(-1),
m_relevance(0)
{
}
@ -69,7 +69,7 @@ public:
: Base(p),
m_id(-1),
m_pinned(false),
m_sample(nullptr),
m_sample(-1),
m_relevance(0)
{
}
@ -78,7 +78,7 @@ public:
: Base(f),
m_id(-1),
m_pinned(false),
m_sample(nullptr),
m_sample(-1),
m_relevance(0)
{
}
@ -87,7 +87,7 @@ public:
: Base(p, f),
m_id(-1),
m_pinned(false),
m_sample(nullptr),
m_sample(-1),
m_relevance(0)
{
}
@ -103,13 +103,13 @@ public:
FT relevance() const { return m_relevance; }
void set_relevance(FT relevance) { m_relevance = relevance; }
Sample_* sample() const { return m_sample; }
void set_sample(Sample_* sample) { m_sample = sample; }
int sample() const { return m_sample; }
void set_sample(int sample) { m_sample = sample; }
const Point& relocated() const { 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---------------------
template <class T>

View File

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

View File

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

View File

@ -17,7 +17,7 @@
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point;
typedef K::FT FT;
typedef K::Segment_2 Segment;
typedef K::Segment_2 Segment;
int main ()
{
@ -37,8 +37,14 @@ int main ()
std::back_inserter(isolated_points), std::back_inserter(edges));
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(edges.size() == 8);
}

View File

@ -56,7 +56,6 @@ void test(std::size_t dataset_size) {
// Count the jumps in depth
auto jumps = count_jumps(octree);
std::cout << "un-graded octree has " << jumps << " jumps" << std::endl;
assert(jumps > 0);
// Grade the octree
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}
EXCLUDE = ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Polygon_mesh_processing/internal
EXCLUDE_SYMBOLS += experimental
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
*
* 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
* computed at all vertices of the graph.

View File

@ -1393,10 +1393,13 @@ public:
}
}
if (inconsistent_classification()) return;
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[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] );
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[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[3] || previous_bitvalue[3]==is_patch_inside_tm1[patch_id_q2] );
}
}
}

View File

@ -1941,6 +1941,7 @@ remove_self_intersections_one_step(std::set<typename boost::graph_traits<Triangl
const bool treat_all_CCs,
const double strong_dihedral_angle,
const double weak_dihedral_angle,
const bool use_smoothing,
const double containment_epsilon,
const Projector& projector,
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
// 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;
@ -2390,6 +2391,8 @@ bool remove_self_intersections(const FaceRange& face_range,
// 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 bool use_smoothing = choose_parameter(get_parameter(np, internal_np::use_smoothing), false);
struct 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(
faces_to_treat, working_face_range, tmesh, step,
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
if(all_fixed && topology_issue)

View File

@ -1032,7 +1032,7 @@ private:
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();
if (i == j) return false;
@ -1046,6 +1046,9 @@ private:
if (j == 2 && i == facesize - 1) return true;
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
@ -1187,7 +1190,7 @@ private:
continue;
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;
}
@ -1295,7 +1298,7 @@ private:
const int &prismid, const unsigned int &faceid)const
{
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 (i == faceid) continue;
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
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<std::vector<unsigned int>*> neighbour_facets;
std::vector<std::vector<unsigned int>*> neighbor_facets;
std::vector<std::vector<unsigned int>> idlistorder;
std::vector<int> neighbour_cover;
std::vector<int> neighbor_cover;
idlistorder.emplace_back(intersect_face[queue[0]]);
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));
neighbours.resize(list.size());
neighbour_facets.resize(list.size());
neighbour_cover.resize(list.size());
neighbors.resize(list.size());
neighbor_facets.resize(list.size());
neighbor_cover.resize(list.size());
for (unsigned int j = 0; j < list.size(); j++) {
neighbours[j] = filtered_intersection[list[j]];
neighbour_facets[j] = &(intersect_face[list[j]]);
if (coverlist[list[j]] == 1) neighbour_cover[j] = 1;
else neighbour_cover[j] = 0;
neighbors[j] = filtered_intersection[list[j]];
neighbor_facets[j] = &(intersect_face[list[j]]);
if (coverlist[list[j]] == 1) neighbor_cover[j] = 1;
else neighbor_cover[j] = 0;
}
for (unsigned int j = 0; j < i; j++) {
@ -1864,7 +1867,7 @@ private:
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) {

View File

@ -98,8 +98,11 @@ void test(const Mesh& mesh,
// tests on non triangular meshes are @todo
if(CGAL::is_triangle(halfedge(f, mesh), mesh))
{
if(PMP::is_degenerate_triangle_face(f, mesh))
assert(get(fnormals, f) == CGAL::NULL_VECTOR);
if (PMP::is_degenerate_triangle_face(f, mesh))
{
if (std::is_same<K, EPECK>())
assert(get(fnormals, f) == CGAL::NULL_VECTOR);
}
else
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());
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());
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());
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)));
assert(PMP::is_on_vertex(loc, source(halfedge(f, g), g), g));
dv = PMP::get_descriptor_from_location(loc, g);
if(const vertex_descriptor* v = boost::get<vertex_descriptor>(&dv)) { } else { assert(false); }
@ -251,22 +254,23 @@ void test_random_entities(const G& g, CGAL::Random& rnd)
loc = PMP::random_location_on_mesh<FT>(g, rnd);
assert(loc.first != boost::graph_traits<G>::null_face());
assert(loc.second[0] >= FT(0) && loc.second[0] <= FT(1) &&
loc.second[1] >= FT(0) && loc.second[1] <= FT(1) &&
loc.second[2] >= FT(0) && loc.second[2] <= FT(1));
loc.second[1] >= FT(0) && loc.second[1] <= FT(1) &&
loc.second[2] >= FT(0) && loc.second[2] <= FT(1));
loc = PMP::random_location_on_face<FT>(f, g, rnd);
assert(loc.first == f);
assert(loc.second[0] >= FT(0) && loc.second[0] <= FT(1) &&
loc.second[1] >= FT(0) && loc.second[1] <= FT(1) &&
loc.second[2] >= FT(0) && loc.second[2] <= FT(1));
loc.second[1] >= FT(0) && loc.second[1] <= FT(1) &&
loc.second[2] >= FT(0) && loc.second[2] <= FT(1));
loc = PMP::random_location_on_halfedge<FT>(h, g, rnd);
assert(loc.first == face(h, g));
assert(loc.second[0] >= FT(0) && loc.second[0] <= FT(1) &&
loc.second[1] >= FT(0) && loc.second[1] <= FT(1) &&
loc.second[2] >= FT(0) && loc.second[2] <= FT(1));
loc.second[1] >= FT(0) && loc.second[1] <= FT(1) &&
loc.second[2] >= FT(0) && loc.second[2] <= FT(1));
int h_id = CGAL::halfedge_index_in_face(h, g);
assert(loc.second[(h_id+2)%3] == FT(0));
assert(loc.second[(h_id + 2) % 3] == FT(0));
}
}
@ -313,8 +317,8 @@ void test_helpers(const G& g, CGAL::Random& rnd)
std::vector<face_descriptor> vec;
PMP::internal::incident_faces(loc, g, std::back_inserter(vec));
assert(PMP::is_on_vertex(loc, source(h, g), g) ||
PMP::is_on_vertex(loc, target(h, g), g) ||
vec.size() == 2);
PMP::is_on_vertex(loc, target(h, g), g) ||
vec.size() == 2);
}
template<typename K, typename G>
@ -432,9 +436,10 @@ void test_locate_in_face(const G& g,
Point_reference p = get(vpm, v);
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)+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) + 1) % 3], FT(0)));
assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g) + 2) % 3], FT(0)));
loc = PMP::locate_vertex<FT>(v, f, g);
assert(loc.first == f);
@ -442,7 +447,7 @@ void test_locate_in_face(const G& g,
loc = PMP::locate_on_halfedge<FT>(h, a, g);
const int h_id = CGAL::halfedge_index_in_face(h, g);
assert(loc.first == f && is_equal(loc.second[(h_id+2)%3], FT(0)));
assert(loc.first == f && is_equal(loc.second[(h_id + 2) % 3], FT(0)));
loc = PMP::locate_in_face(p, f, g, CGAL::parameters::vertex_point_map(vpm).geom_traits(K()));
int v_id = CGAL::vertex_index_in_face(v, f, g);
@ -475,10 +480,11 @@ void test_locate_in_face(const G& g,
neigh_loc.second[(neigh_hd_id+2)%3] = FT(0);
PMP::locate_in_adjacent_face(loc, neigh_f, g);
assert(PMP::locate_in_common_face<FT>(loc, neigh_loc, g));
assert(PMP::locate_in_common_face<FT>(loc, p, neigh_loc, g, CGAL::parameters::vertex_point_map(vpm).geom_traits(K())));
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()), 1e-7));
}
}
@ -536,11 +542,10 @@ struct Locate_with_AABB_tree_Tester // 2D case
// sanitize otherwise some test platforms fail
PMP::internal::snap_location_to_border(loc, g, FT(1e-7));
assert(PMP::is_on_vertex(loc, v, g)); // might fail du to precision issues...
assert(PMP::is_on_vertex(loc, v, g)); // might fail due to precision issues...
assert(is_equal(loc.second[CGAL::vertex_index_in_face(v, loc.first, g)], FT(1)));
assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g)+1)%3], FT(0)));
assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g)+2)%3], FT(0)));
assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g) + 1) % 3], FT(0)));
assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g) + 2) % 3], FT(0)));
assert(is_equal(CGAL::squared_distance(to_p3(
PMP::construct_point<FT>(loc, g, CGAL::parameters::vertex_point_map(vpm))), p3_a), 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));
assert(is_equal(CGAL::squared_distance(to_p3(
PMP::construct_point(loc, g, CGAL::parameters::vertex_point_map(vpm))), p3_a), FT(0)));
assert(PMP::is_in_face(loc, g));
if (std::is_same<K, EPECK>()) {
assert(PMP::is_in_face(loc, g));
}
loc = PMP::locate_with_AABB_tree(CGAL::ORIGIN, tree_b, g, CGAL::parameters::vertex_point_map(vpm_b));
assert(PMP::is_in_face(loc, g));
if (std::is_same<K, EPECK>()) {
assert(PMP::is_in_face(loc, g));
}
loc = PMP::locate(CGAL::ORIGIN, g, CGAL::parameters::vertex_point_map(vpm_b));
assert(PMP::is_in_face(loc, g));
if (std::is_same<K, EPECK>()) {
assert(PMP::is_in_face(loc, g));
}
// ---------------------------------------------------------------------------
Ray_2 r2 = random_2D_ray<CGAL::AABB_tree<AABB_face_graph_traits> >(tree_a, rnd);
loc = PMP::locate_with_AABB_tree(r2, tree_a, g, 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));
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));
Face_location loc = PMP::locate_with_AABB_tree(p3_a, tree_a, g, CGAL::parameters::vertex_point_map(vpm));
assert(is_equal(loc.second[CGAL::vertex_index_in_face(v, loc.first, g)], FT(1)));
assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g)+1)%3], FT(0)));
assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g)+2)%3], FT(0)));
assert(is_equal(CGAL::squared_distance(PMP::construct_point(loc, g), p3_a), FT(0)));
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) + 1) % 3], FT(0)));
assert(is_equal(loc.second[(CGAL::vertex_index_in_face(v, loc.first, g) + 2) % 3], FT(0)));
assert(is_equal(CGAL::squared_distance(PMP::construct_point(loc, g), p3_a), FT(0)));
}
loc = PMP::locate_with_AABB_tree(p3_a, tree_a, g, CGAL::parameters::vertex_point_map(vpm));
assert(is_equal(CGAL::squared_distance(PMP::construct_point(loc, g), p3_a), FT(0)));
if (std::is_same<K, EPECK>()) {
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));
assert(is_equal(CGAL::squared_distance(PMP::construct_point(loc, g), p3_a), FT(0)));
assert(PMP::is_in_face(loc, g));
if (std::is_same<K, EPECK>()) {
assert(is_equal(CGAL::squared_distance(PMP::construct_point(loc, g), p3_a), FT(0)));
assert(PMP::is_in_face(loc, g));
}
loc = PMP::locate_with_AABB_tree(CGAL::ORIGIN, tree_b, g, CGAL::parameters::vertex_point_map(custom_vpm_3D));
assert(PMP::is_in_face(loc, g));
if (std::is_same<K, EPECK>()) {
assert(PMP::is_in_face(loc, g));
}
// 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));
assert(PMP::is_in_face(loc, g));
if (std::is_same<K, EPECK>()) {
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);
@ -848,7 +870,7 @@ void test(CGAL::Random& 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_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_polyhedron<K>("data-coref/elephant_split_2.off", rnd);
}

View File

@ -1,3 +1,2 @@
@INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS}
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();
CGAL::Three::Three::warning("VTK is required to read DCM and BMP files");
CGAL_USE(dirname);
CGAL_USE(ext);
return false;
#else
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_USE(dirname);
CGAL_USE(ext);
CGAL_USE(smooth);
#else
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::property_map<Mesh, CGAL::vertex_point_t>::type VPMap;
typedef typename CGAL::Kernel_traits< typename boost::property_traits<VPMap>::value_type >::Kernel Traits;
double rad_to_deg = 180. / CGAL_PI;
accumulator_set< double,
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 c = get(vpmap, target(next(h, *poly), *poly));
typename Traits::Vector_3 ba(b, a);
typename Traits::Vector_3 bc(b, c);
double cos_angle = (ba * bc)
/ std::sqrt(ba.squared_length() * bc.squared_length());
acc(std::acos(cos_angle) * rad_to_deg);
typename Traits::FT ang = CGAL::approximate_angle(b,a,c);
acc(CGAL::to_double(ang));
}
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);
}
#endif // POLYHEDRON_DEMO_STATISTICS_HELPERS_H

View File

@ -30,9 +30,9 @@ protected:
//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.
void push_neighbours_of(const Vertex_const_handle start, const int ith,
std::vector < Vertex_const_handle > &nextRing,
std::vector < Vertex_const_handle > &all);
void push_neighbors_of(const Vertex_const_handle start, const int ith,
std::vector < Vertex_const_handle > &nextRing,
std::vector < Vertex_const_handle > &all);
//i >= 1, from a currentRing i-1, collect all neighbors, set indices
//to i and store them in nextRing and all.
@ -70,7 +70,7 @@ T_PolyhedralSurf_rings(const TPoly& P)
template < class 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 > &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
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>

View File

@ -30,9 +30,9 @@ protected:
//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.
void push_neighbours_of(const Vertex_const_handle start, const int ith,
std::vector < Vertex_const_handle > &nextRing,
std::vector < Vertex_const_handle > &all);
void push_neighbors_of(const Vertex_const_handle start, const int ith,
std::vector < Vertex_const_handle > &nextRing,
std::vector < Vertex_const_handle > &all);
//i >= 1, from a currentRing i-1, collect all neighbors, set indices
//to i and store them in nextRing and all.
@ -44,7 +44,7 @@ protected:
public:
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,
const int ring_i,
std::vector < Vertex_const_handle >& all);
@ -70,7 +70,7 @@ T_PolyhedralSurf_rings(const TPoly& P)
template < class 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 > &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
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>

View File

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

View File

@ -419,7 +419,8 @@ bool build_triangulation_impl(Tr& tr,
if(finite_cells.empty())
{
std::cout << "WARNING: No finite cells were provided. Only the points will be loaded."<<std::endl;
if (verbose)
std::cout << "WARNING: No finite cells were provided. Only the points will be loaded."<<std::endl;
}
tr.tds().clear(); // not tr.clear() since it calls tr.init() which we don't want
@ -438,14 +439,14 @@ bool build_triangulation_impl(Tr& tr,
success = false;
}
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(verbose) std::cout << "build_infinite_cells went wrong" << std::endl;
success = false;
}
else
std::cout << "build infinite cells done" << std::endl;
if (verbose) std::cout << "build infinite cells done" << std::endl;
tr.tds().set_dimension(3);
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;
}
else
std::cout << "assign neighbors done" << std::endl;
if (verbose) std::cout << "assign neighbors done" << std::endl;
if (verbose)
{
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_simplify_border_t, do_simplify_border, do_simplify_border)
CGAL_add_named_parameter(algorithm_t, algorithm, algorithm)
CGAL_add_named_parameter(use_smoothing_t, use_smoothing, use_smoothing)
//internal
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 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:
int main(int argc, char* argv[])
{
@ -33,8 +44,7 @@ int main(int argc, char* argv[])
++index)
{
auto orientation = polygon.orientation();
auto segment_outer_circle =
SMS::internal::get_segment_outer_circle<Kernel>(*e_it, orientation);
auto segment_outer_circle = get_segment_outer_circle<Kernel>(*e_it, orientation);
auto d = segment_outer_circle.first;
d = d.perpendicular(CGAL::CLOCKWISE);
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:
typedef EigenSolverT Solver;
typedef Scalar NT;
#ifdef DOXYGEN_RUNNING
typedef unspecified_type Matrix;
#else
typedef internal::Get_eigen_matrix<EigenSolverT,NT>::type Matrix;
#endif
typedef Eigen_vector<Scalar> Vector;
// Public operations

View File

@ -413,8 +413,8 @@ namespace nanoflann
checks(checks_IGNORED_), eps(eps_), sorted(sorted_) {}
int checks; //!< Ignored parameter (Kept for compatibility with the FLANN interface).
float eps; //!< search for eps-approximate neighbours (default: 0)
bool sorted; //!< only for radius search, require neighbours sorted by distance (default: true)
float eps; //!< search for eps-approximate neighbors (default: 0)
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;
typedef BranchStruct<NodePtr, DistanceType> BranchSt;

View File

@ -6,6 +6,7 @@
\example Spatial_searching/fuzzy_range_query.cpp
\example Spatial_searching/general_neighbor_searching.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/searching_with_circular_query.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_projection.cpp")
create_single_source_cgal_program("nearest_neighbor_searching.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
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.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::cout << std::endl;
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;
bool search_nearest_neighbour;
bool search_nearest_neighbor;
FT rd;
@ -278,8 +278,8 @@ namespace CGAL {
bool search_nearest;
Priority_higher(bool search_the_nearest_neighbour)
: search_nearest(search_the_nearest_neighbour)
Priority_higher(bool search_the_nearest_neighbor)
: search_nearest(search_the_nearest_neighbor)
{}
//highest priority is smallest distance
@ -296,8 +296,8 @@ namespace CGAL {
bool search_nearest;
Distance_smaller(bool search_the_nearest_neighbour)
:search_nearest(search_the_nearest_neighbour)
Distance_smaller(bool search_the_nearest_neighbor)
:search_nearest(search_the_nearest_neighbor)
{}
//highest priority is smallest distance
@ -325,19 +325,19 @@ namespace CGAL {
int number_of_internal_nodes_visited;
int number_of_leaf_nodes_visited;
int number_of_items_visited;
int number_of_neighbours_computed;
int number_of_neighbors_computed;
// constructor
Iterator_implementation(const Tree& tree, const Query_item& q,const Distance& tr,
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_tree(tree),
PriorityQueue(Priority_higher(search_nearest)),
Item_PriorityQueue(Distance_smaller(search_nearest)),
distance(tr), reference_count(1), number_of_internal_nodes_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;
@ -365,7 +365,7 @@ namespace CGAL {
// rd is the distance of the top of the priority queue to q
rd=The_Root->second;
Compute_the_next_nearest_neighbour();
Compute_the_next_nearest_neighbor();
}
// * operator
@ -380,7 +380,7 @@ namespace CGAL {
operator++()
{
Delete_the_current_item_top();
Compute_the_next_nearest_neighbour();
Compute_the_next_nearest_neighbor();
return *this;
}
@ -405,7 +405,7 @@ namespace CGAL {
s << "Number of points visited:" <<
number_of_items_visited << std::endl;
s << "Number of neighbors computed:" <<
number_of_neighbours_computed << std::endl;
number_of_neighbors_computed << std::endl;
return s;
}
@ -459,21 +459,21 @@ namespace CGAL {
// old top of PriorityQueue has been processed,
// hence update rd
bool next_neighbour_found;
bool next_neighbor_found;
if (!(PriorityQueue.empty()))
{
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);
}
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++;
return next_neighbour_found;
number_of_neighbors_computed++;
return next_neighbor_found;
}
// Without cache
@ -494,37 +494,37 @@ namespace CGAL {
// old top of PriorityQueue has been processed,
// hence update rd
bool next_neighbour_found;
bool next_neighbor_found;
if (!(PriorityQueue.empty()))
{
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);
}
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++;
return next_neighbour_found;
number_of_neighbors_computed++;
return next_neighbor_found;
}
void
Compute_the_next_nearest_neighbour()
Compute_the_next_nearest_neighbor()
{
// compute the next item
bool next_neighbour_found=false;
bool next_neighbor_found=false;
if (!(Item_PriorityQueue.empty())) {
if (search_nearest_neighbour)
next_neighbour_found =
if (search_nearest_neighbor)
next_neighbor_found =
(multiplication_factor*rd > Item_PriorityQueue.top()->second);
else
next_neighbour_found =
next_neighbor_found =
(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();
Node_const_handle N = The_node_top->first->node();
@ -544,7 +544,7 @@ namespace CGAL {
Node_box* upper_box = new Node_box(*B);
lower_box->split(*upper_box,new_cut_dim, new_cut_val);
delete B;
if (search_nearest_neighbour) {
if (search_nearest_neighbor) {
FT distance_to_box_lower =
distance.min_distance_to_rectangle(query_point, *lower_box);
FT distance_to_box_upper =
@ -597,12 +597,15 @@ namespace CGAL {
number_of_leaf_nodes_visited++;
if (node->size() > 0) {
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
}
CGAL_DEPRECATED void Compute_the_next_nearest_neighbour()
{ void Compute_the_next_nearest_neighbor(); }
}; // class Iterator_implementation
}; // class iterator
}; // class

View File

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

View File

@ -138,14 +138,14 @@ public:
typedef typename boost::property_traits<PointPropertyMap>::value_type
Point;
std::shared_ptr<Point> point;
std::size_t idx;
Point point;
std::size_t idx = 0;
public:
No_lvalue_iterator() : point(NULL), idx(0) { }
No_lvalue_iterator(const Point& point) : point(new Point(point)), idx(0) { }
No_lvalue_iterator(const Point& point, int) : point(new Point(point)), idx(Base::Dimension::value) { }
No_lvalue_iterator() : point() { }
No_lvalue_iterator(const Point& point) : point(point) { }
No_lvalue_iterator(const Point& point, int) : point(point), idx(Base::Dimension::value) { }
private:
@ -153,18 +153,15 @@ public:
void increment()
{
++idx;
CGAL_assertion(point != std::shared_ptr<Point>());
}
void decrement()
{
--idx;
CGAL_assertion(point != std::shared_ptr<Point>());
}
void advance(std::ptrdiff_t n)
{
idx += n;
CGAL_assertion(point != std::shared_ptr<Point>());
}
std::ptrdiff_t distance_to(const No_lvalue_iterator& other) const
@ -181,7 +178,7 @@ public:
dereference() const
{
// 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:
Distance_larger(bool search_the_nearest_neighbour)
: search_nearest(search_the_nearest_neighbour)
Distance_larger(bool search_the_nearest_neighbor)
: search_nearest(search_the_nearest_neighbor)
{}
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::Point_with_transformed_distance pd = *it;
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;
}
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++;
for(; it != oins.end();it++){
typename K_search::Point_with_transformed_distance qd = *it;
assert(pd.second <= qd.second);
pd = qd;
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;
}
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
main() {
std::cout << std::setprecision(17);
bool OK=true;
std::cout << "Testing Incremental_neighbor_search\n";
run<Incremental_neighbor_search>();

View File

@ -60,20 +60,23 @@ struct Splitter_test {
typename Orthogonal_incremental_neighbor_search::iterator it = oins.begin();
Point_with_transformed_distance pd = *it;
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;
}
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++;
for(; it != oins.end();it++){
Point_with_transformed_distance qd = *it;
assert(pd.second <= qd.second);
pd = qd;
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;
}
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(points2.begin(),points2.end());

View File

@ -137,43 +137,14 @@ private:
return K().construct_segment_2_object()(s,t);
}
Trisegment_2_ptr CreateTrisegment ( Triedge const& aTriedge ) 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 ) ;
}
Trisegment_2_ptr GetTrisegment ( Vertex_const_handle aNode ) const ;
Comparison_result Compare_offset_against_event_time( FT aT, Vertex_const_handle aNode ) const
{
CGAL_precondition( aNode->is_skeleton() ) ;
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 ;
}
@ -199,8 +170,7 @@ public:
CGAL_assertion ( lNodeT->is_skeleton() ) ;
Vertex_const_handle lSeedNode = aBisector->slope() == POSITIVE ? lNodeS : lNodeT ;
lSeedEvent = CreateTrisegment(lSeedNode) ;
lSeedEvent = GetTrisegment(lSeedNode) ;
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();
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) )
{
@ -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 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 ) ;
//
@ -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>
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));
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() )
{
Triedge const& lEventTriedge = aNode->event_triedge() ;
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
}
r = aNode->trisegment() ;
CGAL_assertion(bool(r));
}
return r ;
}
template<class Ss, class Gt, class Cont, class Visitor>
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 ;
} // namespace CGAL
if ( Is_bisector_defined_by(aBisector,aEa,aEb) )
{
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 //
#endif // CGAL_POLYGON_OFFSET_BUILDER_2_IMPL_H

View File

@ -30,7 +30,8 @@ namespace CGAL {
namespace CGAL_SS_i {
template<class K> struct Has_inexact_constructions
template<class K>
struct Has_inexact_constructions
{
typedef typename K::FT FT ;
@ -42,6 +43,23 @@ template<class K> struct Has_inexact_constructions
>::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)
//
@ -176,10 +194,7 @@ public:
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(); }
} // namespace CGAL
#endif // CGAL_STRAIGHT_SKELETON_AUX_H //
// EOF //
#endif // CGAL_STRAIGHT_SKELETON_AUX_H

View File

@ -113,9 +113,9 @@ Straight_skeleton_builder_2<Gt,Ss,V>::FindEdgeEvent( Vertex_handle aLNode, Verte
if ( GetEdgeEndingAt(lPrevNode) == lTriedge.e2() )
{
// Note that this can be a contour node and in that case GetTrisegment is null and we get
// the middle point, but in that case e2 and e0 are consecutive in the input
// and the middle point is the common extremity and things are fine.
// Note that this can be a contour node and in that case GetTrisegment returns null
// and we get the middle point as a seed, but in that case e2 and e0 are consecutive
// in the input and the middle point is the common extremity thus things are fine.
lTrisegment->set_child_t( GetTrisegment(lPrevNode) ) ;
}
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++ ) ) ;
InitVertexData(lInfNode);
CGAL_assertion(lInfNode->has_null_point());
CGAL_assertion(lInfNode->has_infinite_time());
lRBisector->HBase_base::set_next( lLBisector );
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 lDefiningBorderC = lNewNode->halfedge()->opposite()->prev()->defining_contour_edge();
lNewNode->VBase::set_event_triedge( lEvent.triedge() ) ;
Triedge lTri(lDefiningBorderA,lDefiningBorderB,lDefiningBorderC);
SetVertexTriedge( lNewNode, lTri ) ;
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++ ) ) ;
InitVertexData(lNewFicNode);
CGAL_assertion(lNewFicNode->has_null_point());
CGAL_assertion(lNewFicNode->has_infinite_time());
CrossLink(lNOBisector_R,lNewFicNode);
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_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 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_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 lTriR( lNewNode_R_DefiningBorderA, lNewNode_R_DefiningBorderB, lNewNode_R_DefiningBorderC ) ;

View File

@ -190,23 +190,6 @@ class Rational
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>
struct No_cache
{

View File

@ -187,8 +187,8 @@ inline std::string e2str( E const& e )
ss << "B" << e.id()
<< "[E" << e.defining_contour_edge()->id()
<< ",E" << e.opposite()->defining_contour_edge()->id() << "]"
<< " (/" << ( e.slope() == CGAL::ZERO ? "·" : ( e.slope() == CGAL::NEGATIVE ? "-" : "+" ) )
<< " " << e.opposite()->vertex()->time() << "->" << e.vertex()->time() << ")" ;
<< " (S " << ( e.slope() == CGAL::ZERO ? "0" : ( e.slope() == CGAL::NEGATIVE ? "-" : "+" ) )
<< "; T " << e.opposite()->vertex()->time() << " -> " << e.vertex()->time() << ")" ;
}
else
{
@ -263,7 +263,7 @@ inline std::string newn2str( char const* name, VH const& v, Triedge const& aTrie
#endif
#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_IF(cond) if ((cond)) sEnableTraitsTrace = true ;
# 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 )
{
// @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 ;
aV->set_trisegment(aTrisegment) ;
}
// Null if aV is a contour node

View File

@ -13,12 +13,14 @@
#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/Cartesian_converter.h>
#include <boost/shared_ptr.hpp>
#include <boost/intrusive_ptr.hpp>
#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 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 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() );
}
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_>
@ -201,20 +276,8 @@ private :
CGAL_assertion( handle_assigned(tgt_halfedge) ) ;
tvit->VBase::set_halfedge(tgt_halfedge);
Target_halfedge_handle tgt_striedge_e0, tgt_striedge_e1, tgt_striedge_e2 ;
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) ) ;
if(svit->trisegment()) // contour nodes do not have trisegments
tvit->set_trisegment(cvt(svit->trisegment()));
}
Target_halfedge_iterator thit = aTarget.halfedges_begin();

View File

@ -62,8 +62,6 @@ public:
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() ; }
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