Merge branch 'master' into SMSP-Add_example_with_locate-GF

This commit is contained in:
Mael 2019-10-21 09:06:30 +02:00 committed by GitHub
commit cbe1cfc750
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
90 changed files with 2024 additions and 916 deletions

17
.github/workflows/cmake-all.yml vendored Normal file
View File

@ -0,0 +1,17 @@
name: CMake all CGAL
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
with:
fetch-depth: 0
- name: install dependencies
run: sudo apt-get install -y libboost-dev libboost-program-options-dev libmpfr-dev libeigen3-dev
- name: configure all
run: mkdir build && cd build && CXX=clang++ cmake -DWITH_examples=ON -DWITH_tests=ON -DWITH_demos=ON ..

View File

@ -91,7 +91,7 @@ Arr_naive_point_location<Arrangement>::locate(const Point_2& p) const
else if (! fh->is_unbounded() && fh->number_of_outer_ccbs() > 0) else if (! fh->is_unbounded() && fh->number_of_outer_ccbs() > 0)
{ {
// As we have already some other containing face, one face must be // As we have already some other containing face, one face must be
// contained inside the other. Two check that, we select a // contained inside the other. To check that, we select a
// representative vertex of inner_f and check whether it is contained // representative vertex of inner_f and check whether it is contained
// in our current face. // in our current face.

View File

@ -98,6 +98,7 @@ public:
//friend class declarations: //friend class declarations:
friend class Trapezoidal_decomposition_2<Traits>; friend class Trapezoidal_decomposition_2<Traits>;
friend struct internal::Non_recursive_td_map_item_destructor<Traits>;
#ifdef CGAL_PM_FRIEND_CLASS #ifdef CGAL_PM_FRIEND_CLASS
#if defined(__SUNPRO_CC) || defined(__PGI) || defined(__INTEL_COMPILER) #if defined(__SUNPRO_CC) || defined(__PGI) || defined(__INTEL_COMPILER)
@ -114,7 +115,10 @@ public:
friend class In_face_iterator; friend class In_face_iterator;
#endif #endif
#endif #endif
~Td_active_edge(){
if (this->refs()==1)
internal::Non_recursive_td_map_item_destructor<Traits>(*this);
}
/*! \class /*! \class
* Inner class Data derived from Rep class * Inner class Data derived from Rep class
*/ */
@ -281,6 +285,10 @@ public:
/*! Access DAG node. */ /*! Access DAG node. */
Dag_node* dag_node() const {return ptr()->p_node; } //m_dag_node;} Dag_node* dag_node() const {return ptr()->p_node; } //m_dag_node;}
bool is_last_reference() const
{
return this->refs()==1;
}
//@} //@}

View File

@ -95,6 +95,7 @@ public:
//friend class declarations: //friend class declarations:
friend class Trapezoidal_decomposition_2<Traits>; friend class Trapezoidal_decomposition_2<Traits>;
friend struct internal::Non_recursive_td_map_item_destructor<Traits>;
#ifdef CGAL_PM_FRIEND_CLASS #ifdef CGAL_PM_FRIEND_CLASS
#if defined(__SUNPRO_CC) || defined(__PGI) || defined(__INTEL_COMPILER) #if defined(__SUNPRO_CC) || defined(__PGI) || defined(__INTEL_COMPILER)
@ -154,7 +155,14 @@ public:
Data* ptr() const { return (Data*)(PTR); } Data* ptr() const { return (Data*)(PTR); }
public:
~Td_active_trapezoid(){
if (this->refs()==1)
internal::Non_recursive_td_map_item_destructor<Traits>(*this);
}
private:
#ifndef CGAL_TD_DEBUG #ifndef CGAL_TD_DEBUG
@ -414,6 +422,11 @@ public:
/*! Access DAG node. */ /*! Access DAG node. */
Dag_node* dag_node() const {return ptr()->p_node; } Dag_node* dag_node() const {return ptr()->p_node; }
bool is_last_reference() const
{
return this->refs()==1;
}
void clear_neighbors() void clear_neighbors()
{ {
set_lb(Td_map_item(0)); set_lb(Td_map_item(0));
@ -421,6 +434,11 @@ public:
set_rb(Td_map_item(0)); set_rb(Td_map_item(0));
set_rt(Td_map_item(0)); set_rt(Td_map_item(0));
} }
void non_recursive_clear_neighbors()
{
internal::Non_recursive_td_map_item_destructor<Traits>(*this);
}
//@} //@}

View File

@ -129,7 +129,10 @@ public:
Data(Vertex_const_handle _v, Halfedge_const_handle _cw_he, Data(Vertex_const_handle _v, Halfedge_const_handle _cw_he,
Dag_node* _p_node) : Dag_node* _p_node) :
v(_v), cw_he(_cw_he), p_node(_p_node) v(_v), cw_he(_cw_he), p_node(_p_node)
{} {
CGAL_assertion( _cw_he==Halfedge_const_handle()
|| _cw_he->source() == v );
}
~Data() {} ~Data() {}
@ -176,9 +179,8 @@ public:
*/ */
inline void set_cw_he(Halfedge_const_handle he) inline void set_cw_he(Halfedge_const_handle he)
{ {
ptr()->cw_he = ((cw_he() != Traits::empty_he_handle()) && ptr()->cw_he = he->twin()->source()==ptr()->v ? he->twin() : he;
(cw_he()->direction() != he->direction())) ? CGAL_assertion( ptr()->v == ptr()->cw_he->source() );
he->twin() : he;
} }
/*! Reset the first he going clockwise starting at 12 o'clock. /*! Reset the first he going clockwise starting at 12 o'clock.

View File

@ -68,8 +68,8 @@ public:
//bool operator!() const { return PTR == 0; } //MICHAL: maybe use ptr(), and also can change to is_null or something similar //bool operator!() const { return PTR == 0; } //MICHAL: maybe use ptr(), and also can change to is_null or something similar
bool is_null() const { return PTR == 0; } bool is_null() const { return PTR == 0; }
protected:
Rep * ptr() const { return (Rep*) PTR; } Rep * ptr() const { return (Rep*) PTR; }
protected:
//Rep *& ptr() { return (Rep*) PTR; } //Rep *& ptr() { return (Rep*) PTR; }
void set_ptr(Rep* rep) { PTR = rep; } void set_ptr(Rep* rep) { PTR = rep; }
@ -126,7 +126,7 @@ protected:
public: public:
void operator()(Td_active_trapezoid& t) const void operator()(Td_active_trapezoid& t) const
{ {
t.clear_neighbors(); t.non_recursive_clear_neighbors();
} }
template < typename Tp > template < typename Tp >
@ -209,7 +209,49 @@ public:
} }
//d'tor //d'tor
~Td_dag_node() { } ~Td_dag_node()
{
// The following code is used to avoid recursive calls to ~Handle
// Node being holding elements of type Td_dag_node_handle
if (!this->is_null() && this->refs()==1)
{
std::vector<Td_dag_node_handle> children;
if (!node()->m_left_child.is_null())
{
children.push_back(node()->m_left_child);
node()->m_left_child.reset();
}
if (!node()->m_right_child.is_null())
{
children.push_back(node()->m_right_child);
node()->m_right_child.reset();
}
while(!children.empty())
{
Td_dag_node_handle child = children.back();
children.pop_back();
Node* child_node = (Node*) child.ptr();
if (child_node != NULL)
{
if (child.refs()==1)
{
if (!child_node->m_left_child.is_null())
{
children.push_back(child_node->m_left_child);
child_node->m_left_child.reset();
}
if( !child_node->m_right_child.is_null() )
{
children.push_back(child_node->m_right_child);
child_node->m_right_child.reset();
}
}
}
}
}
}
//information retrieval //information retrieval

View File

@ -49,6 +49,111 @@
namespace CGAL { namespace CGAL {
namespace internal{
// struct used to avoid recursive deletion of elements of
// Td_map_item. Td_active_edge and Td_active_edge_item are
// both refering to elements of the same type creating
// recursive call to ~Handle() if we let the regular
// calls of destructors. Here elements are copied in
// a vector and the true deletion is done when the vector
// is cleared.
template <class Traits>
struct Non_recursive_td_map_item_destructor
{
typedef typename Traits::Td_map_item Td_map_item;
typedef typename Traits::Td_active_trapezoid Td_active_trapezoid;
typedef typename Traits::Td_active_edge Td_active_edge;
struct Child_visitor
{
typedef void result_type;
std::vector<Td_map_item>& m_queue;
Child_visitor(std::vector<Td_map_item>& queue)
: m_queue(queue)
{}
void operator()(Td_active_trapezoid& item)
{
if (item.is_last_reference())
m_queue.push_back(item);
}
void operator()(Td_active_edge& item)
{
if (item.is_last_reference())
m_queue.push_back(item);
}
template <class T>
void operator()(T&) {} // nothing to do for the other types of the variant
};
struct Item_visitor
{
typedef void result_type;
Child_visitor& m_child_visitor;
Item_visitor(Child_visitor& child_visitor)
: m_child_visitor(child_visitor)
{}
void operator()(Td_active_trapezoid& item)
{
boost::apply_visitor(m_child_visitor, item.lb());
boost::apply_visitor(m_child_visitor, item.lt());
boost::apply_visitor(m_child_visitor, item.rb());
boost::apply_visitor(m_child_visitor, item.rt());
item.clear_neighbors();
}
void operator()(Td_active_edge& item)
{
boost::apply_visitor(m_child_visitor, item.next());
item.set_next(Td_map_item(0));
}
template <class T>
void operator()(T&) {} // nothing to do for the other types of the variant
};
std::vector<Td_map_item> queue;
Child_visitor child_visitor;
Item_visitor item_visitor;
Non_recursive_td_map_item_destructor(Td_active_trapezoid& item)
: child_visitor(queue)
, item_visitor(child_visitor)
{
item_visitor(item);
while (!queue.empty())
{
Td_map_item item = queue.back();
queue.pop_back();
boost::apply_visitor(item_visitor, item);
}
}
Non_recursive_td_map_item_destructor(Td_active_edge& item)
: child_visitor(queue)
, item_visitor(child_visitor)
{
item_visitor(item);
while (!queue.empty())
{
Td_map_item item = queue.back();
queue.pop_back();
boost::apply_visitor(item_visitor, item);
}
}
};
} // internal
/*! \class Trapezoidal_decomposition_2 /*! \class Trapezoidal_decomposition_2
* parameters Traits * parameters Traits
* Description Implementation for a planar trapezoidal map also known as * Description Implementation for a planar trapezoidal map also known as
@ -1447,7 +1552,9 @@ public:
{ {
if (do_rebuild && not_within_limits()) if (do_rebuild && not_within_limits())
{ {
#ifdef CGAL_TD_DEBUG
std::cout << "starting over after " << number_of_curves() << std::flush; std::cout << "starting over after " << number_of_curves() << std::flush;
#endif
start_over = true; start_over = true;
clear(); clear();
break; break;
@ -1853,14 +1960,14 @@ public:
ds->filter(representatives, Td_active_edge_item(*traits)); ds->filter(representatives, Td_active_edge_item(*traits));
#ifndef CGAL_TD_DEBUG #ifndef CGAL_TD_DEBUG
CGAL_warning(sz == representatives.size()); CGAL_warning(sz <= representatives.size());
#else #else
unsigned long rep = representatives.size(); unsigned long rep = representatives.size();
if (sz != rep) { if (sz > rep) {
std::cerr << "\nnumber_of_curves()=" << sz; std::cerr << "\nnumber_of_curves()=" << sz;
std::cerr << "\nrepresentatives.size()=" << rep; std::cerr << "\nrepresentatives.size()=" << rep;
CGAL_assertion(number_of_curves()==representatives.size()); CGAL_assertion(number_of_curves()<=representatives.size());
} }
#endif #endif
@ -1873,7 +1980,15 @@ public:
} }
} }
if (! container.empty()) { if (! container.empty()) {
CGAL::cpp98::random_shuffle(container.begin(),container.end()); if (sz != representatives.size())
{
std::sort(container.begin(),container.end());
typename Halfedge_container::iterator last = std::unique(container.begin(), container.end());
container.erase(last, container.end());
}
CGAL_assertion(sz==container.size());
// CGAL::cpp98::random_shuffle(container.begin(),container.end()); // already done in insert()
} }
return sz; return sz;
} }

View File

@ -229,7 +229,7 @@ deactivate_trapezoid(Dag_node& trpz_node, Dag_node* active_node) const
CGAL_precondition(traits->is_td_trapezoid(trpz_node.get_data())); CGAL_precondition(traits->is_td_trapezoid(trpz_node.get_data()));
if (Td_active_trapezoid* trap = if (Td_active_trapezoid* trap =
boost::get<Td_active_trapezoid>(&trpz_node.get_data())) boost::get<Td_active_trapezoid>(&trpz_node.get_data()))
trap->clear_neighbors(); trap->non_recursive_clear_neighbors();
trpz_node.set_data(Td_inactive_trapezoid()); trpz_node.set_data(Td_inactive_trapezoid());
if (active_node) trpz_node.set_left_child(*active_node); if (active_node) trpz_node.set_left_child(*active_node);
} }
@ -510,10 +510,10 @@ update_vtx_cw_he_after_remove(Halfedge_const_handle old_he,
Halfedge_const_handle cw_he(boost::apply_visitor(cw_he_visitor(), vtx_item)); Halfedge_const_handle cw_he(boost::apply_visitor(cw_he_visitor(), vtx_item));
if ((old_he == cw_he) || (old_he->twin() == cw_he)) { if ((old_he == cw_he) || (old_he->twin() == cw_he)) {
Halfedge_const_handle new_he = cw_he->twin()->prev(); Halfedge_const_handle new_he = cw_he->twin()->next();
if (new_he != old_he) if (new_he != cw_he)
boost::apply_visitor(set_cw_he_visitor(new_he), vtx_item); boost::apply_visitor(set_cw_he_visitor(new_he), vtx_item);
else boost::apply_visitor(reset_cw_he_visitor(), vtx_item); else boost::apply_visitor(reset_cw_he_visitor(), vtx_item); // dangling edge removed
} }
} }

View File

@ -69,9 +69,9 @@ read_vtk_image_data(vtkImageData* vtk_image, Image_3::Own owning = Image_3::OWN_
image->ydim = dims[1]; image->ydim = dims[1];
image->zdim = dims[2]; image->zdim = dims[2];
image->vdim = 1; image->vdim = 1;
image->vx = spacing[0]; image->vx = (spacing[0] == 0) ? 1 : spacing[0];
image->vy = spacing[1]; image->vy = (spacing[1] == 0) ? 1 : spacing[1];
image->vz = spacing[2]; image->vz = (spacing[2] == 0) ? 1 : spacing[2];
image->tx = static_cast<float>(offset[0]); image->tx = static_cast<float>(offset[0]);
image->ty = static_cast<float>(offset[1]); image->ty = static_cast<float>(offset[1]);
image->tz = static_cast<float>(offset[2]); image->tz = static_cast<float>(offset[2]);

View File

@ -25,14 +25,24 @@
#include <CGAL/Classification/Feature_set.h> #include <CGAL/Classification/Feature_set.h>
#include <CGAL/Classification/Label_set.h> #include <CGAL/Classification/Label_set.h>
#if (CV_MAJOR_VERSION < 3)
#include <cv.h> #include <opencv2/opencv.hpp>
#include <ml.h>
//In opencv version 2.X the first digit is named EPOCH,
//until version 3.0 where EPOCH disappears and it becomes MAJOR. Hence this
//weird condition
#ifdef CV_VERSION_EPOCH
#if CV_VERSION_MAJOR == 4 && CV_VERSION_MINOR>= 11
#include <opencv2/ml.hpp>
#else
#include <opencv2/ml/ml.hpp>
#endif
#else #else
#include <opencv/cv.h> #include <opencv2/ml.hpp>
#include <opencv/ml.h>
#endif #endif
namespace CGAL { namespace CGAL {
namespace Classification { namespace Classification {

View File

@ -7,7 +7,7 @@
\cgalPkgPicture{Logo-ConeSpanners.png} \cgalPkgPicture{Logo-ConeSpanners.png}
\cgalPkgSummaryBegin \cgalPkgSummaryBegin
\cgalPkgAuthors{Weisheng Si, Quincy Tse and Frédérk Paradis} \cgalPkgAuthors{Weisheng Si, Quincy Tse and Frédérik Paradis}
\cgalPkgDesc{This package provides functors for constructing two kinds of cone-based spanners: \cgalPkgDesc{This package provides functors for constructing two kinds of cone-based spanners:
Yao graph and Theta graph, given a set of vertices on the plane and the directions of cone boundaries. Yao graph and Theta graph, given a set of vertices on the plane and the directions of cone boundaries.
Both exact and inexact constructions are supported. Both exact and inexact constructions are supported.

View File

@ -140,6 +140,8 @@ supporting <a href="https://isocpp.org/wiki/faq/cpp14">C++14</a> or later.
It may work for older versions of the above listed compilers. It may work for older versions of the above listed compilers.
\attention Recent versions of CMake are needed for recent versions of MS Visual C++. Please refer to CMake's documentation for further information.
\section secconfigwithcmake Configuring CGAL with CMake \section secconfigwithcmake Configuring CGAL with CMake

View File

@ -3,22 +3,23 @@
var url_re = /(cgal\.geometryfactory\.com\/CGAL\/doc\/|doc\.cgal\.org\/)(master|latest|(\d\.\d+|\d\.\d+\.\d+))\//; var url_re = /(cgal\.geometryfactory\.com\/CGAL\/doc\/|doc\.cgal\.org\/)(master|latest|(\d\.\d+|\d\.\d+\.\d+))\//;
var url_local = /.*\/doc_output\//; var url_local = /.*\/doc_output\//;
var current_version_local = '4.14-beta1' var current_version_local = '5.0-beta2'
var all_versions = [ var all_versions = [
'master', 'master',
'latest', 'latest',
'4.14', '5.0',
'4.13.1', '4.14.1',
'4.12.2', '4.13.2',
'4.11.3', '4.12.2',
'4.10.2', '4.11.3',
'4.9.1', '4.10.2',
'4.8.2', '4.9.1',
'4.7', '4.8.2',
'4.6.3', '4.7',
'4.5.2', '4.6.3',
'4.4', '4.5.2',
'4.3' '4.4',
'4.3'
]; ];
function build_select(current_version) { function build_select(current_version) {

View File

@ -498,7 +498,7 @@ table.memberdecls {
white-space: nowrap; white-space: nowrap;
} }
.memItemRight { .memItemRight, .memTemplItemRight {
width: 100%; width: 100%;
} }

View File

@ -3,22 +3,23 @@
var url_re = /(cgal\.geometryfactory\.com\/CGAL\/doc\/|doc\.cgal\.org\/)(master|latest|(\d\.\d+|\d\.\d+\.\d+))\//; var url_re = /(cgal\.geometryfactory\.com\/CGAL\/doc\/|doc\.cgal\.org\/)(master|latest|(\d\.\d+|\d\.\d+\.\d+))\//;
var url_local = /.*\/doc_output\//; var url_local = /.*\/doc_output\//;
var current_version_local = '4.14-beta1' var current_version_local = '5.0-beta2'
var all_versions = [ var all_versions = [
'master', 'master',
'latest', 'latest',
'4.14', '5.0',
'4.13.1', '4.14.1',
'4.12.2', '4.13.2',
'4.11.3', '4.12.2',
'4.10.2', '4.11.3',
'4.9.1', '4.10.2',
'4.8.2', '4.9.1',
'4.7', '4.8.2',
'4.6.3', '4.7',
'4.5.2', '4.6.3',
'4.4', '4.5.2',
'4.3' '4.4',
'4.3'
]; ];
function build_select(current_version) { function build_select(current_version) {

View File

@ -498,7 +498,7 @@ table.memberdecls {
white-space: nowrap; white-space: nowrap;
} }
.memItemRight { .memItemRight, .memTemplItemRight {
width: 100%; width: 100%;
} }

View File

@ -3,22 +3,23 @@
var url_re = /(cgal\.geometryfactory\.com\/CGAL\/doc\/|doc\.cgal\.org\/)(master|latest|(\d\.\d+|\d\.\d+\.\d+))\//; var url_re = /(cgal\.geometryfactory\.com\/CGAL\/doc\/|doc\.cgal\.org\/)(master|latest|(\d\.\d+|\d\.\d+\.\d+))\//;
var url_local = /.*\/doc_output\//; var url_local = /.*\/doc_output\//;
var current_version_local = '4.14-beta1' var current_version_local = '5.0-beta2'
var all_versions = [ var all_versions = [
'master', 'master',
'latest', 'latest',
'4.14', '5.0',
'4.13.1', '4.14.1',
'4.12.2', '4.13.2',
'4.11.3', '4.12.2',
'4.10.2', '4.11.3',
'4.9.1', '4.10.2',
'4.8.2', '4.9.1',
'4.7', '4.8.2',
'4.6.3', '4.7',
'4.5.2', '4.6.3',
'4.4', '4.5.2',
'4.3' '4.4',
'4.3'
]; ];
function build_select(current_version) { function build_select(current_version) {

View File

@ -466,7 +466,7 @@ table.memberdecls {
white-space: nowrap; white-space: nowrap;
} }
.memItemRight { .memItemRight, .memTemplItemRight {
width: 100%; width: 100%;
} }

View File

@ -1,5 +1,6 @@
Algebraic_foundations Algebraic_foundations
Circulator Circulator
Geomview
Installation Installation
Interval_support Interval_support
Kernel_23 Kernel_23

View File

@ -39,9 +39,6 @@
namespace CGAL namespace CGAL
{ {
typedef CGAL::Exact_predicates_inexact_constructions_kernel Local_kernel;
typedef Local_kernel::Point_3 Local_point;
typedef Local_kernel::Vector_3 Local_vector;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
namespace internal namespace internal
@ -58,90 +55,77 @@ namespace internal
n.z()+((p.x()-q.x())*(p.y()+q.y()))); n.z()+((p.x()-q.x())*(p.y()+q.y())));
} }
inline template <class Point, class Vector>
Local_vector compute_normal_of_face(const std::vector<Local_point>& points) Vector compute_normal_of_face(const std::vector<Point>& points)
{ {
Local_vector normal(CGAL::NULL_VECTOR); Vector normal(CGAL::NULL_VECTOR);
unsigned int nb = 0; unsigned int nb = 0;
for (std::size_t i=0; i<points.size(); ++i) for (std::size_t i=0; i<points.size(); ++i)
{ {
newell_single_step_3(points[i], points[(i+1)%points.size()], normal); internal::newell_single_step_3(points[i], points[(i+1)%points.size()],
normal);
++nb; ++nb;
} }
assert(nb>0); assert(nb>0);
return (Local_kernel::Construct_scaled_vector_3()(normal, 1.0/nb)); return (typename Kernel_traits<Vector>::Kernel::Construct_scaled_vector_3()
(normal, 1.0/nb));
} }
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// Structs to transform any CGAL point/vector into a Local_point/Local_vector // Structs to transform any CGAL point/vector into a Local_point/Local_vector
template<typename K> template<typename K, typename Local_kernel>
struct Geom_utils struct Geom_utils
{ {
static Local_point get_local_point(const typename K::Point_2& p) static typename Local_kernel::Point_3 get_local_point(const typename K::Point_2& p)
{ {
CGAL::Cartesian_converter<K, Local_kernel> converter; CGAL::Cartesian_converter<K, Local_kernel> converter;
return Local_point(converter(p.x()), 0, converter(p.y())); return Local_point(converter(p.x()), 0, converter(p.y()));
} }
static Local_point get_local_point(const typename K::Weighted_point_2& p) static typename Local_kernel::Point_3 get_local_point(const typename K::Weighted_point_2& p)
{ {
typename K::Point_2 lp(p); typename K::Point_2 lp(p);
return Geom_utils<K>::get_local_point(lp); return Geom_utils<K, Local_kernel>::get_local_point(lp);
} }
static Local_point get_local_point(const typename K::Point_3& p) static typename Local_kernel::Point_3 get_local_point(const typename K::Point_3& p)
{ {
CGAL::Cartesian_converter<K, Local_kernel> converter; CGAL::Cartesian_converter<K, Local_kernel> converter;
return converter(p); return converter(p);
} }
static Local_point get_local_point(const typename K::Weighted_point_3& p) static typename Local_kernel::Point_3 get_local_point(const typename K::Weighted_point_3& p)
{ {
typename K::Point_3 lp(p); typename K::Point_3 lp(p);
return Geom_utils<K>::get_local_point(lp); return Geom_utils<K, Local_kernel>::get_local_point(lp);
} }
static Local_vector get_local_vector(const typename K::Vector_2& v) static typename Local_kernel::Vector_3 get_local_vector(const typename K::Vector_2& v)
{ {
CGAL::Cartesian_converter<K, Local_kernel> converter; CGAL::Cartesian_converter<K, Local_kernel> converter;
return Local_vector(converter(v.x()), 0, converter(v.y())); return Local_vector(converter(v.x()), 0, converter(v.y()));
} }
static Local_vector get_local_vector(const typename K::Vector_3& v) static typename Local_kernel::Vector_3 get_local_vector(const typename K::Vector_3& v)
{ {
CGAL::Cartesian_converter<K, Local_kernel> converter; CGAL::Cartesian_converter<K, Local_kernel> converter;
return converter(v); return converter(v);
} }
}; };
// Specialization for Local_kernel, because there is no need of convertion here. // Specialization when K==Local_kernel, because there is no need of convertion here.
template<> template<typename Local_kernel>
struct Geom_utils<Local_kernel> struct Geom_utils<Local_kernel, Local_kernel>
{ {
static Local_point get_local_point(const Local_kernel::Point_2& p) static typename Local_kernel::Point_3 get_local_point(const typename Local_kernel::Point_2& p)
{ return Local_point(p.x(), 0, p.y()); } { return typename Local_kernel::Point_3(p.x(), 0, p.y()); }
static Local_point get_local_point(const Local_kernel::Weighted_point_2& p) static typename Local_kernel::Point_3 get_local_point(const typename Local_kernel::Weighted_point_2& p)
{ return Local_point(p.point().x(), 0, p.point().y());} { return typename Local_kernel::Point_3(p.point().x(), 0, p.point().y());}
static const Local_point & get_local_point(const Local_kernel::Point_3& p) static const typename Local_kernel::Point_3 & get_local_point(const typename Local_kernel::Point_3& p)
{ return p; } { return p; }
static Local_point get_local_point(const Local_kernel::Weighted_point_3& p) static typename Local_kernel::Point_3 get_local_point(const typename Local_kernel::Weighted_point_3& p)
{ return Local_point(p);} { return typename Local_kernel::Point_3(p);}
static Local_vector get_local_vector(const Local_kernel::Vector_2& v) static typename Local_kernel::Vector_3 get_local_vector(const typename Local_kernel::Vector_2& v)
{ return Local_vector(v.x(), 0, v.y()); } { return typename Local_kernel::Vector_3(v.x(), 0, v.y()); }
static const Local_vector& get_local_vector(const Local_kernel::Vector_3& v) static const typename Local_kernel::Vector_3& get_local_vector(const typename Local_kernel::Vector_3& v)
{ return v; } { return v; }
}; };
////////////////////////////////////////////////////////////////
// Global function to simplify function calls.
template<typename KPoint>
Local_point get_local_point(const KPoint& p)
{
return Geom_utils<typename CGAL::Kernel_traits<KPoint>::Kernel>::
get_local_point(p);
}
template<typename KVector>
Local_vector get_local_vector(const KVector& v)
{
return Geom_utils<typename CGAL::Kernel_traits<KVector>::Kernel>::
get_local_vector(v);
}
} // End namespace internal } // End namespace internal
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -149,6 +133,10 @@ template<typename BufferType=float, typename IndexType=std::size_t>
class Buffer_for_vao class Buffer_for_vao
{ {
public: public:
typedef CGAL::Exact_predicates_inexact_constructions_kernel Local_kernel;
typedef Local_kernel::Point_3 Local_point;
typedef Local_kernel::Vector_3 Local_vector;
Buffer_for_vao(std::vector<BufferType>* pos=nullptr, Buffer_for_vao(std::vector<BufferType>* pos=nullptr,
std::vector<IndexType>* indices=nullptr, std::vector<IndexType>* indices=nullptr,
CGAL::Bbox_3* bbox=nullptr, CGAL::Bbox_3* bbox=nullptr,
@ -220,7 +208,7 @@ public:
{ {
if (!has_position()) return (std::size_t)-1; if (!has_position()) return (std::size_t)-1;
Local_point p=internal::get_local_point(kp); Local_point p=get_local_point(kp);
add_point_in_buffer(p, *m_pos_buffer); add_point_in_buffer(p, *m_pos_buffer);
if (m_bb!=nullptr) if (m_bb!=nullptr)
@ -293,7 +281,7 @@ public:
template<typename KNormal> template<typename KNormal>
void face_begin(const KNormal& kv) void face_begin(const KNormal& kv)
{ {
m_normal_of_face=internal::get_local_vector(kv); m_normal_of_face=get_local_vector(kv);
face_begin_internal(false, true); face_begin_internal(false, true);
} }
@ -302,7 +290,7 @@ public:
void face_begin(const CGAL::Color& c, const KNormal& kv) void face_begin(const CGAL::Color& c, const KNormal& kv)
{ {
m_color_of_face=c; m_color_of_face=c;
m_normal_of_face=internal::get_local_vector(kv); m_normal_of_face=get_local_vector(kv);
face_begin_internal(true, true); face_begin_internal(true, true);
} }
@ -314,7 +302,7 @@ public:
{ {
if (!is_a_face_started()) return false; if (!is_a_face_started()) return false;
Local_point p=internal::get_local_point(kp); Local_point p=get_local_point(kp);
if (m_points_of_face.empty() || m_points_of_face.back()!=p) // TODO test if the distance between prev point and kp is smaller than an epsilon (?? not sure ??) if (m_points_of_face.empty() || m_points_of_face.back()!=p) // TODO test if the distance between prev point and kp is smaller than an epsilon (?? not sure ??)
{ {
m_points_of_face.push_back(p); m_points_of_face.push_back(p);
@ -331,7 +319,7 @@ public:
{ {
if (add_point_in_face(kp)) if (add_point_in_face(kp))
{ {
m_vertex_normals_for_face.push_back(internal::get_local_vector(p_normal)); m_vertex_normals_for_face.push_back(get_local_vector(p_normal));
return true; return true;
} }
return false; return false;
@ -388,7 +376,8 @@ public:
} }
Local_vector normal=(m_started_face_has_normal?m_normal_of_face: Local_vector normal=(m_started_face_has_normal?m_normal_of_face:
internal::compute_normal_of_face(m_points_of_face)); internal::compute_normal_of_face
<Local_point, Local_vector>(m_points_of_face));
if (m_points_of_face.size()==3) if (m_points_of_face.size()==3)
{ triangular_face_end_internal(normal); } // Triangle: no need to triangulate { triangular_face_end_internal(normal); } // Triangle: no need to triangulate
@ -411,7 +400,7 @@ public:
template<typename KPoint> template<typename KPoint>
static void add_point_in_buffer(const KPoint& kp, std::vector<float>& buffer) static void add_point_in_buffer(const KPoint& kp, std::vector<float>& buffer)
{ {
Local_point p=internal::get_local_point(kp); Local_point p=get_local_point(kp);
buffer.push_back(p.x()); buffer.push_back(p.x());
buffer.push_back(p.y()); buffer.push_back(p.y());
buffer.push_back(p.z()); buffer.push_back(p.z());
@ -421,7 +410,7 @@ public:
template<typename KVector> template<typename KVector>
static void add_normal_in_buffer(const KVector& kv, std::vector<float>& buffer) static void add_normal_in_buffer(const KVector& kv, std::vector<float>& buffer)
{ {
Local_vector n=internal::get_local_vector(kv); Local_vector n=get_local_vector(kv);
buffer.push_back(n.x()); buffer.push_back(n.x());
buffer.push_back(n.y()); buffer.push_back(n.y());
buffer.push_back(n.z()); buffer.push_back(n.z());
@ -796,6 +785,21 @@ protected:
{ add_normal_in_buffer(kv, *m_gouraud_normal_buffer); } { add_normal_in_buffer(kv, *m_gouraud_normal_buffer); }
} }
protected:
// Shortcuts to simplify function calls.
template<typename KPoint>
static Local_point get_local_point(const KPoint& p)
{
return internal::Geom_utils<typename CGAL::Kernel_traits<KPoint>::Kernel, Local_kernel>::
get_local_point(p);
}
template<typename KVector>
static Local_vector get_local_vector(const KVector& v)
{
return internal::Geom_utils<typename CGAL::Kernel_traits<KVector>::Kernel, Local_kernel>::
get_local_vector(v);
}
protected: protected:
// Types usefull for triangulation // Types usefull for triangulation
struct Vertex_info struct Vertex_info

View File

@ -446,6 +446,20 @@ public:
} }
protected: protected:
// Shortcuts to simplify function calls.
template<typename KPoint>
static Local_point get_local_point(const KPoint& p)
{
return internal::Geom_utils<typename CGAL::Kernel_traits<KPoint>::Kernel, Local_kernel>::
get_local_point(p);
}
template<typename KVector>
static Local_vector get_local_vector(const KVector& v)
{
return internal::Geom_utils<typename CGAL::Kernel_traits<KVector>::Kernel, Local_kernel>::
get_local_vector(v);
}
void compile_shaders() void compile_shaders()
{ {
rendering_program_face.removeAllShaders(); rendering_program_face.removeAllShaders();

View File

@ -43,9 +43,7 @@ namespace Qt {
class CGAL_QT_EXPORT GraphicsItem : public QObject, public QGraphicsItem { class CGAL_QT_EXPORT GraphicsItem : public QObject, public QGraphicsItem {
Q_OBJECT Q_OBJECT
#ifdef CGAL_HEADER_ONLY
Q_INTERFACES(QGraphicsItem) Q_INTERFACES(QGraphicsItem)
#endif
public Q_SLOTS: public Q_SLOTS:

View File

@ -1,144 +1,180 @@
Release History Release History
=============== ===============
Release 5.0 [Release 5.0](https://github.com/CGAL/cgal/releases/tag/releases%2FCGAL-5.0)
----------- -----------
Release date: September 2019 Release date: October 2019
### Polygonal Surface Reconstruction (new package) ### General changes
- This package provides a method for piecewise planar object reconstruction from point clouds. - CGAL 5.0 is the first release of CGAL that requires a C++ compiler
The method takes as input an unordered point set sampled from a piecewise planar object with the support of C++14 or later. The new list of supported
and outputs a compact and watertight surface mesh interpolating the input point set. compilers is:
The method assumes that all necessary major planes are provided (or can be extracted from - Visual C++ 14.0 (from Visual Studio 2015 Update 3) or later,
the input point set using the shape detection method described in Point Set Shape Detection, - Gnu g++ 6.3 or later (on Linux or MacOS),
or any other alternative methods).The method can handle arbitrary piecewise planar objects - LLVM Clang version 8.0 or later (on Linux or MacOS), and
and is capable of recovering sharp features and is robust to noise and outliers. - Apple Clang compiler versions 7.0.2 and 10.0.1 (on MacOS).
- Since CGAL 4.9, CGAL can be used as a header-only library, with
### Solver Interface dependencies. Since CGAL 5.0, that is now the default, unless
specified differently in the (optional) CMake configuration.
- Added concepts and models for solving Mixed Integer Programming (MIP) problems with or without constraints.
## 2D Triangulations
- Added range types and functions that return ranges, for example
for all vertices, which enables to use C++11 for-loops.
- **Breaking change**: Removed the functions `CGAL::Constrained_triangulation_plus_2::
vertices_in_constraint_{begin/end}(Vertex_handle va, Vertex_handle vb) const;`,
and `CGAL::Constrained_triangulation_plus_2::remove_constraint((Vertex_handle va, Vertex_handle vb)`,
that is a pair of vertex handles is no longer a key for a polyline constraint.
Users must use a version prior to 5.0 if they need this functionality.
- **Breaking change**: Removed the deprecated classes `CGAL::Regular_triangulation_euclidean_traits_2`, `CGAL::Regular_triangulation_filtered_traits_2`. Users must use a version prior to 5.0 if they need these classes.
- **Breaking change**: The constructor and the `insert()` function of `CGAL::Triangulation_2` which takes
a range of points as argument no longer performs a `spatial_sort()` of the points.
- Add constructor and `insert()` function to `CGAL::Triangulation_2` that takes a range of points with info.
- **Breaking change**: The graph traits enabling CGAL's 2D triangulations to be used as a parameter
for any graph-based algorithm of CGAL (or boost) have been improved to fully model the `FaceGraph` concept.
In addition, only the finite simplicies (those not incident to the infinite vertex) of the 2D triangulations
are now visibile through this scope. The complete triangulation can still be accessed as a graph,
by using the graph traits of the underlying triangulation data structure (usually,
`CGAL::Triangulation_data_structure_2`).
- Introduced a new face base class, `Triangulation_face_base_with_id_2` which enables storing
user-defined integer IDs in the face of any 2D triangulation, a precondition to use some
BGL algorithms.
### 3D Triangulations
- Added range types and functions that return ranges, for example
for all vertices, which enables to use C++11 for-loops.
- **Breaking change**: The constructor and the `insert()` function of `CGAL::Triangulation_3` which takes
a range of points as argument no longer performs a `spatial_sort()` of the points.
- Add constructor and `insert()` function to `CGAL::Triangulation_3` that takes a range of points with info.
### Surface Mesh ### [Polygonal Surface Reconstruction](https://doc.cgal.org/5.0/Manual/packages.html#PkgPolygonalSurfaceReconstruction) (new package)
- New functions to read and write using the PLY format,
`CGAL::read_ply()` and `CGAL::write_ply()`, allowing to save and
load additional property maps of the surface mesh.
### 3D Point Set - This package provides a method for piecewise planar object reconstruction from point clouds.
- The PLY IO functions now take an additional optional parameter to The method takes as input an unordered point set sampled from a piecewise planar object
read/write comments from/in the PLY header. and outputs a compact and watertight surface mesh interpolating the input point set.
The method assumes that all necessary major planes are provided (or can be extracted from
the input point set using the shape detection method described in Point Set Shape Detection,
or any other alternative methods).The method can handle arbitrary piecewise planar objects
and is capable of recovering sharp features and is robust to noise and outliers. See also
the associated [blog entry](https://www.cgal.org/2019/08/05/Polygonal_surface_reconstruction/).
### Point Set Processing ### [Shape Detection](https://doc.cgal.org/5.0/Manual/packages.html#PkgShapeDetection) (major changes)
- **Breaking change**: the old API using iterators and overloads - **Breaking change:** The concept `ShapeDetectionTraits` has been renamed to [`EfficientRANSACTraits`](https://doc.cgal.org/5.0/Shape_detection/classEfficientRANSACTraits.html).
for optional parameters is now removed (it was deprecated since - **Breaking change:** The `Shape_detection_3` namespace has been renamed to [`Shape_detection`](https://doc.cgal.org/5.0/Shape_detection/annotated.html).
CGAL 4.12). The current (and now only) API uses ranges and Named - Added a new, generic implementation of region growing. This enables for example applying region growing to inputs such as 2D and 3D point sets,
Parameters. or models of the [`FaceGraph`](https://doc.cgal.org/5.0/BGL/classFaceGraph.html) concept. Learn more about this new algorithm with this [blog entry](https://www.cgal.org/2019/07/30/Shape_detection/).
- Added the possibility to use the named parameter
`neighbor_radius` to use spherical neighbor queries instead of
K-nearest neighbors queries for the following functions:
`CGAL::bilateral_smooth_point_set()`,
`CGAL::jet_estimate_normals()`, `CGAL::jet_smooth_point_set()`,
`CGAL::mst_orient_normals()`, `CGAL::pca_estimate_normals()` and
`CGAL::remove_outliers()`.
### Polygon Mesh Processing ### [dD Geometry Kernel](https://doc.cgal.org/5.0/Manual/packages.html#PkgKernelD)
- Added the function `CGAL::Polygon_mesh_processing::non_manifold_vertices()`, - A new exact kernel, [`Epeck_d`](https://doc.cgal.org/5.0/Kernel_d/structCGAL_1_1Epeck__d.html), is now available.
which can be used to collect all the non-manifold vertices (i.e. pinched vertices,
or vertices appearing in multiple umbrellas) of a mesh. ### [2D and 3D Linear Geometry Kernel](https://doc.cgal.org/5.0/Manual/packages.html#PkgKernel23)
- Introduced a wide range of new functions related to location of queries on a triangle mesh, - Added a new concept, [`ComputeApproximateAngle_3`](https://doc.cgal.org/5.0/Kernel_23/classKernel_1_1ComputeApproximateAngle__3.html),
such as `CGAL::Polygon_mesh_processing::locate(Point, Mesh)`, . The location of a point on a triangle mesh to the 3D Kernel concepts to compute the approximate angle between two 3D vectors. Corresponding functors
is expressed as the pair of a face and the barycentric coordinates of the point in this face, in the model ([`Compute_approximate_angle_3`](https://doc.cgal.org/5.0/Kernel_23/classKernel.html#a183c9ac358a4ccddc04e680f8ed16c0b))
enabling robust manipulation of locations (for example, intersections of two 3D segments living and free function ([`approximate_angle`](https://doc.cgal.org/5.0/Kernel_23/group__approximate__angle__grp.html))
within the same face). have also been added.
- Added the function `CGAL::Polygon_mesh_processing::centroid()`, which computes - The following objects are now hashable and thus trivially usable
the centroid of a closed triangle mesh. with [`std::unordered_set`](https://en.cppreference.com/w/cpp/container/unordered_set)
- Added the functions `CGAL::Polygon_mesh_processing::stitch_boundary_cycle()` and and [`std::unordered_map`](https://en.cppreference.com/w/cpp/header/unordered_map):
`CGAL::Polygon_mesh_processing::stitch_boundary_cycles()`, which can be used `CGAL::Aff_transformation_2`, `CGAL::Aff_transformation_3`,
to try and merge together geometrically compatible but combinatorially different halfedges `CGAL::Bbox_2`, `CGAL::Bbox_3`, `CGAL::Circle_2`,
`CGAL::Iso_cuboid_3`, `CGAL::Iso_rectangle_2`, `CGAL::Point_2`,
`CGAL::Point_3`, `CGAL::Segment_2`, `CGAL::Segment_3`,
`CGAL::Sphere_3`, `CGAL::Vector_2`, `CGAL::Vector_3`,
`CGAL::Weighted_point_2` and `CGAL::Weighted_point_3`.
### [Polygon Mesh Processing](https://doc.cgal.org/latest/Manual/packages.html#PkgPolygonMeshProcessing)
- Introduced a [wide range of new functions](https://doc.cgal.org/5.0/Polygon_mesh_processing/index.html#title36)
related to location of queries on a triangle mesh,
such as [`CGAL::Polygon_mesh_processing::locate(Point, Mesh)`](https://doc.cgal.org/5.0/Polygon_mesh_processing/group__PMP__locate__grp.html#gada09bd8740ba69ead9deca597d53cf15).
The location of a point on a triangle mesh is expressed as the pair of a face and the barycentric
coordinates of the point in this face, enabling robust manipulation of locations
(for example, intersections of two 3D segments living within the same face).
- Added the mesh smoothing function [`smooth_mesh()`](https://doc.cgal.org/5.0/Polygon_mesh_processing/group__PMP__meshing__grp.html#gaa0551d546f6ab2cd9402bea12d8332a3),
which can be used to improve the quality of triangle elements based on various geometric characteristics.
- Added the shape smoothing function [`smooth_shape()`](https://doc.cgal.org/5.0/Polygon_mesh_processing/group__PMP__meshing__grp.html#gaaa083ec78bcecf351e04d1bbf460b4a2),
which can be used to smooth the surface of a triangle mesh, using the mean curvature flow to perform noise removal.
(See also the new entry in the [User Manual](https://doc.cgal.org/5.0/Polygon_mesh_processing/index.html#title8))
- Added the function [`CGAL::Polygon_mesh_processing::centroid()`](https://doc.cgal.org/5.0/Polygon_mesh_processing/group__measure__grp.html#ga6da5119ce2c50729fda11a90ae7fb9ba),
which computes the centroid of a closed triangle mesh.
- Added the functions [`CGAL::Polygon_mesh_processing::stitch_boundary_cycle()`](https://doc.cgal.org/5.0/Polygon_mesh_processing/group__PMP__repairing__grp.html#ga9c12c4878c08a117b3733bb45f1a34cf)
and [`CGAL::Polygon_mesh_processing::stitch_boundary_cycles()`](https://doc.cgal.org/5.0/Polygon_mesh_processing/group__PMP__repairing__grp.html#ga24d5ae37f62064b3fc576ba48a4ccc63),
which can be used to try and merge together geometrically compatible but combinatorially different halfedges
that belong to the same boundary cycle. that belong to the same boundary cycle.
- It is now possible to pass a face-size property map to `CGAL::Polygon_mesh_processing::keep_large_connected_components()` - It is now possible to pass a face-size property map to [`CGAL::Polygon_mesh_processing::keep_large_connected_components()`](https://doc.cgal.org/5.0/Polygon_mesh_processing/group__keep__connected__components__grp.html#ga48e7b3e6922ee78cf8ce801e3e325d9a)
and `CGAL::Polygon_mesh_processing::keep_largest_connected_components()`, enabling users to define and [`CGAL::Polygon_mesh_processing::keep_largest_connected_components()`](https://doc.cgal.org/5.0/Polygon_mesh_processing/group__keep__connected__components__grp.html#ga68c6c29dfc6a26a6a2f8befe6944f19d), enabling users to define
how the size of a face is computed (the size of the connected component is the sum of the sizes of its faces). how the size of a face is computed (the size of the connected component is the sum of the sizes of its faces).
If no property map is passed, the behavior is unchanged to previous versions: the size If no property map is passed, the behavior is unchanged to previous versions: the size
of a connected component is the number of faces it contains. of a connected component is the number of faces it contains.
- Added the mesh smoothing function `smooth_mesh()`, which can be used to - Added the function [`CGAL::Polygon_mesh_processing::non_manifold_vertices()`](https://doc.cgal.org/5.0/Polygon_mesh_processing/group__PMP__repairing__grp.html#ga36098d2415efd0604b7b996163bc22db),
improve the quality of triangle elements based on various geometric characteristics. which can be used to collect all the non-manifold vertices (i.e. pinched vertices,
- Added the shape smoothing function `smooth_shape()`, which can be used to or vertices appearing in multiple umbrellas) of a mesh.
smooth the surface of a triangle mesh, using the mean curvature flow to perform noise removal.
### IO Streams ### [3D Point Set](https://doc.cgal.org/5.0/Manual/packages.html#PkgPointSet3)
- **Breaking change:** The API of `CGAL::Color` has been cleaned up. - The [PLY IO functions](https://doc.cgal.org/5.0/Point_set_3/group__PkgPointSet3IO.html) now take an additional optional parameter to
read/write comments from/in the PLY header.
### Shape Detection ### [Point Set Processing](https://doc.cgal.org/latest/Manual/packages.html#PkgPointSetProcessing3)
- Added a new generic implementation of region growing. - **Breaking change**: the API using iterators and overloads for optional parameters (deprecated since
- New region growing can be launched on points in 2D and 3D and on a face graph. CGAL 4.12) has been removed. The current (and now only) API uses ranges and Named Parameters.
- **Breaking change:** ShapeDetectionTraits is renamed to EfficientRANSACTraits. - Added the possibility to use the named parameter
- **Breaking change:** Shape_detection_3 namespace is renamed to Shape_detection. [`neighbor_radius`](https://doc.cgal.org/5.0/Point_set_processing_3/group__psp__namedparameters.html#PSP_neighbor_radius)
to use spherical neighbor queries instead of K-nearest neighbors queries for the following functions:
[`CGAL::bilateral_smooth_point_set()`](https://doc.cgal.org/5.0/Point_set_processing_3/group__PkgPointSetProcessing3Algorithms.html#ga4f82723e2f0bb33f3677e29e0208a256),
[`CGAL::jet_estimate_normals()`](https://doc.cgal.org/5.0/Point_set_processing_3/group__PkgPointSetProcessing3Algorithms.html#ga0cd0f87de690d4edf82740e856efa491),
[`CGAL::jet_smooth_point_set()`](https://doc.cgal.org/5.0/Point_set_processing_3/group__PkgPointSetProcessing3Algorithms.html#ga549402c0a8a8b6b71875181e93961521),
[`CGAL::mst_orient_normals()`](https://doc.cgal.org/5.0/Point_set_processing_3/group__PkgPointSetProcessing3Algorithms.html#ga50c98d5c5ae5535bce6f32eddbd03f33),
[`CGAL::pca_estimate_normals()`](https://doc.cgal.org/5.0/Point_set_processing_3/group__PkgPointSetProcessing3Algorithms.html#ga8c642da96a025ab32445aeb6cc219b0b) and
[`CGAL::remove_outliers()`](https://doc.cgal.org/5.0/Point_set_processing_3/group__PkgPointSetProcessing3Algorithms.html#gafd0b5a21ec5042e4bca09cb43f1847f9).
### 3D Boolean Operations on Nef Polyhedra ### [2D Triangulations](https://doc.cgal.org/5.0/Manual/packages.html#PkgTriangulation2)
- Added a function to convert a Nef_polyhedron_3 to a polygon soup: `CGAL::convert_nef_polyhedron_to_polygon_soup()` - **Breaking change**: Removed the deprecated functions `CGAL::Constrained_triangulation_plus_2::
vertices_in_constraint_{begin/end}(Vertex_handle va, Vertex_handle vb) const;`,
and `CGAL::Constrained_triangulation_plus_2::remove_constraint(Vertex_handle va, Vertex_handle vb)`,
that is a pair of vertex handles is no longer a key for a polyline constraint.
Users must use a version prior to 5.0 if they need this functionality.
- **Breaking change**: Removed the deprecated classes `CGAL::Regular_triangulation_euclidean_traits_2`,
`CGAL::Regular_triangulation_filtered_traits_2`. Users must use a version prior to 5.0 if they need these classes.
- **Breaking change**: The [graph traits](https://doc.cgal.org/5.0/BGL/group__PkgBGLTraits.html) enabling CGAL's 2D triangulations to be used as a parameter
for any graph-based algorithm of CGAL (or boost) have been improved to fully model the [`FaceGraph`](https://doc.cgal.org/5.0/BGL/classFaceGraph.html) concept.
In addition, only the finite simplicies (those not incident to the infinite vertex) of the 2D triangulations
are now visibile through this scope. The complete triangulation can still be accessed as a graph,
by using the graph traits of the underlying triangulation data structure (usually,
[`CGAL::Triangulation_data_structure_2`](https://doc.cgal.org/5.0/TDS_2/classCGAL_1_1Triangulation__data__structure__2.html)).
- **Breaking change**: The `insert()` function
of
[`CGAL::Triangulation_2`](https://doc.cgal.org/latest/Triangulation_2/classCGAL_1_1Triangulation__2.html)
which takes a range of points as argument is now guaranteed to
insert the points following the order of `InputIterator`. Note
that this change only affects the base class `Triangulation_2`
and not any derived class, such as `Delaunay_triangulation_2`.
- Added a new [constructor](https://doc.cgal.org/5.0/Triangulation_2/classCGAL_1_1Triangulation__2.html#a6cfa7d3aaa375a25d217858b49e2eb07=)
and [`insert()`](https://doc.cgal.org/5.0/Triangulation_2/classCGAL_1_1Triangulation__2.html#ac5e9bc8adef80dc01a0b31c2d0234545)
function to [`CGAL::Triangulation_2`](https://doc.cgal.org/5.0/Triangulation_2/classCGAL_1_1Triangulation__2.html)
that takes a range of points with info.
- Introduced a new face base class, [`Triangulation_face_base_with_id_2`](https://doc.cgal.org/5.0/BGL/classCGAL_1_1Triangulation__face__base__with__id__2.html)
which enables storing user-defined integer IDs in the face of any 2D triangulation, a precondition to use some
BGL algorithms.
- Added range types and functions that return ranges, for example for all vertices, enabling the use of `C++11` `for`-loops.
See [this new example](https://doc.cgal.org/5.0/Triangulation_2/Triangulation_2_2for_loop_2_8cpp-example.html) for a usage demonstration.
### 2D and 3D Linear Geometry Kernel ### [3D Triangulations](https://doc.cgal.org/5.0/Manual/packages.html#PkgTriangulation3)
- Add `ComputeApproximateAngle_3` in the 2D/3D Kernel concept to compute - **Breaking change**: The [constructor](https://doc.cgal.org/5.0/Triangulation_3/classCGAL_1_1Triangulation__3.html#a63f67cf6aaadcee14318cf56a36d247a)
the approximate dihedral angle between 2 vectors. Corresponding functors and the [`insert()`](https://doc.cgal.org/5.0/Triangulation_3/classCGAL_1_1Triangulation__3.html#ad3353128386bbb51f79d0263e7f67337)
in the model (`Compute_approximate_angle_3`) and free function (`approximate_angle`) function of [`CGAL::Triangulation_3`](https://doc.cgal.org/5.0/Triangulation_3/classCGAL_1_1Triangulation__3.html)
are also added. which take a range of points as argument are now guaranteed to
- The following objects are now hashable and thus trivially usable insert the points following the order of `InputIterator`. Note
with `std::unordered_set` and `std::unordered_map`: that this change only affects the base class `Triangulation_3`
`CGAL::Aff_transformation_2`, `CGAL::Aff_transformation_3`, and not any derived class, such as `Delaunay_triangulation_3`.
`CGAL::Bbox_2`, `CGAL::Bbox_3`, `CGAL::Circle_2`, - Added constructor and [`insert()`](https://doc.cgal.org/5.0/Triangulation_3/classCGAL_1_1Triangulation__3.html#a8aa85f88733d30aa3ec5385538e13ace)
`CGAL::Iso_cuboid_3`, `CGAL::Iso_rectangle_2`, `CGAL::Point_2`, function to `CGAL::Triangulation_3` that takes a range of points with info.
`CGAL::Point_3`, `CGAL::Segment_2`, `CGAL::Segment_3`, - Added range types and functions that return ranges, for example for all vertices, which enables to use C++11 for-loops.
`CGAL::Sphere_3`, `CGAL::Vector_2`, `CGAL::Vector_3`, See [this new example](https://doc.cgal.org/5.0/Triangulation_3/Triangulation_3_2for_loop_8cpp-example.html) for a usage demonstration.
`CGAL::Weighted_point_2` and `CGAL::Weighted_point_3`.
### dD Geometry Kernel ### [Surface Mesh](https://doc.cgal.org/5.0/Manual/packages.html#PkgSurfaceMesh)
- New exact kernel `Epeck_d` - Introduced new functions to read and write using the PLY format,
[`CGAL::read_ply()`](https://doc.cgal.org/5.0/Surface_mesh/group__PkgSurface__mesh.html#ga42f6ad486ddab74e13d3dc53f511c343)
and [`CGAL::write_ply()`](https://doc.cgal.org/5.0/Surface_mesh/group__PkgSurface__mesh.html#ga77bbb79d449c981895eedb6c3c23bd14),
enabling users to save and load additional property maps of the surface mesh.
### [CGAL and Solvers](https://doc.cgal.org/5.0/Manual/packages.html#PkgSolverInterface)
- Added [concepts](https://doc.cgal.org/5.0/Solver_interface/group__PkgSolverInterfaceConcepts.html)
and [models](https://doc.cgal.org/5.0/Solver_interface/group__PkgSolverInterfaceRef.html)
for solving Mixed Integer Programming (MIP) problems with or without constraints.
### [3D Boolean Operations on Nef Polyhedra](https://doc.cgal.org/5.0/Manual/packages.html#PkgNef3)
- Added a function to convert a Nef_polyhedron_3 to a polygon soup: [`CGAL::convert_nef_polyhedron_to_polygon_soup()`](https://doc.cgal.org/5.0/Nef_3/group__PkgNef3IOFunctions.html#ga28a9eb4da0cd6153f0c16f7f9eaf6665)
### [IO Streams](https://doc.cgal.org/5.0/Manual/packages.html#PkgStreamSupport)
- **Breaking change:** The API of [`CGAL::Color`](https://doc.cgal.org/5.0/Stream_support/classCGAL_1_1Color.html) has been cleaned up.
- Added new functions to support some parts of the WKT file format:
* [`CGAL::read_WKT()`](https://doc.cgal.org/5.0/Stream_support/group__PkgStreamSupportRef.html#gad2872abfe6fcf17d705d38567fdd6248)
* [`CGAL::read_point_WKT()`](https://doc.cgal.org/5.0/Stream_support/group__PkgStreamSupportRef.html#gadbd2705b183e467507abd2f167446eba)
* [`CGAL::read_multi_point_WKT()`](https://doc.cgal.org/5.0/Stream_support/group__PkgStreamSupportRef.html#ga4fb72e49a1fd385bbed35ea20297aa8d)
* [`CGAL::read_linestring_WKT()`](https://doc.cgal.org/5.0/Stream_support/group__PkgStreamSupportRef.html#gaaa236308b9da5dbf217ef281fdb55de4)
* [`CGAL::read_multi_linestring_WKT()`](https://doc.cgal.org/5.0/Stream_support/group__PkgStreamSupportRef.html#gad6046c7f9d36512b8a014be82c1e2220)
* [`CGAL::read_polygon_WKT()`](https://doc.cgal.org/5.0/Stream_support/group__PkgStreamSupportRef.html#gaa36ccd3ac4b3fe3e3fd8a76715c56b9a)
* [`CGAL::read_multi_polygon_WKT()`](https://doc.cgal.org/5.0/Stream_support/group__PkgStreamSupportRef.html#ga4ceaa71b9cb3b3f7984bed19afff6fc6)
* [`CGAL::write_point_WKT()`](https://doc.cgal.org/5.0/Stream_support/group__PkgStreamSupportRef.html#gab1a2d277b43c218bf128a2056eb53ced)
* [`CGAL::write_polygon_WKT()`](https://doc.cgal.org/5.0/Stream_support/group__PkgStreamSupportRef.html#gab5365a4726893aa4f51739ede63f5a09)
* [`CGAL::write_linestring_WKT()`](https://doc.cgal.org/5.0/Stream_support/group__PkgStreamSupportRef.html#gaa37ed77d1a01567b93c872a48198efa6)
* [`CGAL::write_multi_point_WKT()`](https://doc.cgal.org/5.0/Stream_support/group__PkgStreamSupportRef.html#ga98de4b4e5cccb370febe5daf66bb582d)
* [`CGAL::write_multi_polygon_WKT()`](https://doc.cgal.org/5.0/Stream_support/group__PkgStreamSupportRef.html#ga4ded40ab50f57e0b410640e28964935e)
* [`CGAL::write_multi_linestring_WKT()`](https://doc.cgal.org/5.0/Stream_support/group__PkgStreamSupportRef.html#ga219987f7a9c0b871c1733aa0c38f26b3)
### IO Streams
- Added new functions to support some parts of the WKT file format:
- `CGAL::read_point_WKT()`
- `CGAL::read_multi_point_WKT()`
- `CGAL::read_linestring_WKT()`
- `CGAL::read_multi_linestring_WKT()`
- `CGAL::read_polygon_WKT()`
- `CGAL::read_multi_polygon_WKT()`
- `CGAL::write_point_WKT()`
- `CGAL::write_polygon_WKT()`
- `CGAL::write_linestring_WKT()`
- `CGAL::write_multi_point_WKT()`
- `CGAL::write_multi_polygon_WKT()`
- `CGAL::write_multi_linestring_WKT()`
- `CGAL:read_WKT()`
Release 4.14 Release 4.14
------------ ------------

View File

@ -925,7 +925,10 @@ if(NOT CGAL_HEADER_ONLY)
${CMAKE_BINARY_DIR}/config/CGALConfig.cmake ${CMAKE_BINARY_DIR}/config/CGALConfig.cmake
DESTINATION ${CGAL_INSTALL_CMAKE_DIR} ) DESTINATION ${CGAL_INSTALL_CMAKE_DIR} )
else() else()
configure_file(${CMAKE_CURRENT_LIST_DIR}/lib/cmake/CGAL/CGALConfig-installation-dirs.cmake.in
${CMAKE_BINARY_DIR}/config/CGALConfig-installation-dirs.cmake)
install(FILES install(FILES
${CMAKE_BINARY_DIR}/config/CGALConfig-installation-dirs.cmake
${CMAKE_CURRENT_LIST_DIR}/lib/cmake/CGAL/CGALConfig.cmake ${CMAKE_CURRENT_LIST_DIR}/lib/cmake/CGAL/CGALConfig.cmake
DESTINATION ${CGAL_INSTALL_CMAKE_DIR} ) DESTINATION ${CGAL_INSTALL_CMAKE_DIR} )
endif() endif()

View File

@ -69,6 +69,11 @@ function(create_single_source_cgal_program firstfile )
add_to_cached_list( CGAL_EXECUTABLE_TARGETS ${exe_name} ) add_to_cached_list( CGAL_EXECUTABLE_TARGETS ${exe_name} )
target_link_libraries(${exe_name} PRIVATE CGAL::CGAL) target_link_libraries(${exe_name} PRIVATE CGAL::CGAL)
foreach(comp ${CGAL_REQUESTED_COMPONENTS})
if(TARGET CGAL::CGAL_${comp})
target_link_libraries(${exe_name} PRIVATE CGAL::CGAL_${comp})
endif()
endforeach()
if(CGAL_3RD_PARTY_LIBRARIES) if(CGAL_3RD_PARTY_LIBRARIES)
target_link_libraries(${exe_name} PRIVATE ${CGAL_3RD_PARTY_LIBRARIES}) target_link_libraries(${exe_name} PRIVATE ${CGAL_3RD_PARTY_LIBRARIES})
endif() endif()

View File

@ -8,9 +8,9 @@ if ( NOT CGAL_GENERATOR_SPECIFIC_SETTINGS_FILE_INCLUDED )
set(CGAL_AUTO_LINK_ENABLED TRUE) set(CGAL_AUTO_LINK_ENABLED TRUE)
endif() endif()
if ( MSVC15 ) if ( MSVC_TOOLSET_VERSION )
set(CGAL_TOOLSET "vc150") set(CGAL_TOOLSET "vc${MSVC_TOOLSET_VERSION}")
message( STATUS "Using VC15 compiler." ) message( STATUS "Using VC toolset ${MSVC_TOOLSET_VERSION}." )
elseif ( MSVC14 ) elseif ( MSVC14 )
set(CGAL_TOOLSET "vc140") set(CGAL_TOOLSET "vc140")
message( STATUS "Using VC14 compiler." ) message( STATUS "Using VC14 compiler." )

View File

@ -3,7 +3,7 @@ if(CGAL_Qt5_moc_and_resource_files_included)
endif() endif()
set(CGAL_Qt5_moc_and_resource_files_included TRUE) set(CGAL_Qt5_moc_and_resource_files_included TRUE)
if(NOT CGAL_HEADER_ONLY) if(NOT CGAL_HEADER_ONLY AND CGAL_BUILDING_LIBS)
qt5_wrap_cpp(_CGAL_Qt5_MOC_FILES_private qt5_wrap_cpp(_CGAL_Qt5_MOC_FILES_private
${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/GraphicsViewNavigation.h ${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/GraphicsViewNavigation.h
${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/DemosMainWindow.h ${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/DemosMainWindow.h
@ -16,6 +16,7 @@ if(NOT CGAL_HEADER_ONLY)
${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/manipulatedFrame.h ${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/manipulatedFrame.h
${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/qglviewer.h ${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/qglviewer.h
${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/image_interface.h ${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/image_interface.h
TARGET CGAL_Qt5
) )
endif()#CGAL_HEADER_ONLY endif()#CGAL_HEADER_ONLY

View File

@ -96,8 +96,8 @@ function(CGAL_setup_CGAL_dependencies target)
use_CGAL_LEDA_support(${target} ${keyword}) use_CGAL_LEDA_support(${target} ${keyword})
endif() endif()
if (CGAL_HEADER_ONLY) if (NOT CGAL_HEADER_ONLY)
target_compile_definitions(${target} ${keyword} CGAL_HEADER_ONLY=1) target_compile_definitions(${target} ${keyword} CGAL_NOT_HEADER_ONLY=1)
endif() endif()
if (RUNNING_CGAL_AUTO_TEST OR CGAL_TEST_SUITE) if (RUNNING_CGAL_AUTO_TEST OR CGAL_TEST_SUITE)
target_compile_definitions(${target} ${keyword} CGAL_TEST_SUITE=1) target_compile_definitions(${target} ${keyword} CGAL_TEST_SUITE=1)

View File

@ -192,6 +192,11 @@ endmacro()
# Get path, convert backslashes as ${ENV_${var}} # Get path, convert backslashes as ${ENV_${var}}
getenv_path(TBB_ROOT) getenv_path(TBB_ROOT)
if(NOT ENV_TBB_ROOT)
getenv_path(TBBROOT)
set(ENV_TBB_ROOT ${ENV_TBBROOT})
endif()
# initialize search paths # initialize search paths
set(TBB_PREFIX_PATH ${TBB_ROOT} ${ENV_TBB_ROOT}) set(TBB_PREFIX_PATH ${TBB_ROOT} ${ENV_TBB_ROOT})
set(TBB_INC_SEARCH_PATH "") set(TBB_INC_SEARCH_PATH "")

View File

@ -9,22 +9,27 @@ set(list_of_whitelisted_headers_txt [=[
CGAL/IO/read_ply_points.h CGAL/IO/read_ply_points.h
CGAL/IO/write_ply_points.h CGAL/IO/write_ply_points.h
CGAL/Surface_mesh_parameterization/internal/shortest_path.h CGAL/Surface_mesh_parameterization/internal/shortest_path.h
CGAL/Three/Edge_container.h
CGAL/Three/exceptions.h CGAL/Three/exceptions.h
CGAL/Three/Polyhedron_demo_plugin_interface.h CGAL/Three/Point_container.h
CGAL/Three/Scene_interface.h
CGAL/Three/Scene_item_with_properties.h
CGAL/Three/Scene_zoomable_item_interface.h
CGAL/Three/Viewer_interface.h
CGAL/Three/Polyhedron_demo_io_plugin_interface.h CGAL/Three/Polyhedron_demo_io_plugin_interface.h
CGAL/Three/Scene_draw_interface.h
CGAL/Three/Scene_item_config.h
CGAL/Three/Scene_print_item_interface.h
CGAL/Three/TextRenderer.h
CGAL/Three/Polyhedron_demo_plugin_helper.h CGAL/Three/Polyhedron_demo_plugin_helper.h
CGAL/Three/Polyhedron_demo_plugin_interface.h
CGAL/Three/Primitive_container.h
CGAL/Three/Scene_draw_interface.h
CGAL/Three/Scene_group_item.h CGAL/Three/Scene_group_item.h
CGAL/Three/Scene_interface.h
CGAL/Three/Scene_item_config.h
CGAL/Three/Scene_item.h CGAL/Three/Scene_item.h
CGAL/Three/Scene_item_rendering_helper.h
CGAL/Three/Scene_item_with_properties.h
CGAL/Three/Scene_print_item_interface.h
CGAL/Three/Scene_transparent_interface.h CGAL/Three/Scene_transparent_interface.h
CGAL/Three/Scene_zoomable_item_interface.h
CGAL/Three/TextRenderer.h
CGAL/Three/Triangle_container.h
CGAL/Three/Viewer_config.h CGAL/Three/Viewer_config.h
CGAL/Three/Viewer_interface.h
]=]) ]=])

View File

@ -173,14 +173,21 @@ CGAL_VERSION: Defined in <CGAL/version.h>
# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1900) # elif defined(BOOST_MSVC) && (BOOST_MSVC < 1900)
// vc12: // vc12:
# define CGAL_LIB_TOOLSET "vc120" # define CGAL_LIB_TOOLSET "vc120"
# elif defined(BOOST_MSVC) # elif defined(BOOST_MSVC) && (BOOST_MSVC < 1910)
// vc14: // vc14:
# define CGAL_LIB_TOOLSET "vc140" # define CGAL_LIB_TOOLSET "vc140"
# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1920)
// vc141:
# define CGAL_LIB_TOOLSET "vc141"
# elif defined(BOOST_MSVC)
// vc142:
# define CGAL_LIB_TOOLSET "vc142"
# elif defined(__BORLANDC__) # elif defined(__BORLANDC__)
// CBuilder 6: // CBuilder 6:

View File

@ -30,6 +30,11 @@
#ifndef CGAL_CONFIG_H #ifndef CGAL_CONFIG_H
#define CGAL_CONFIG_H #define CGAL_CONFIG_H
// CGAL is header-only by default since CGAL-5.0.
#if !defined(CGAL_HEADER_ONLY) && ! CGAL_NOT_HEADER_ONLY
# define CGAL_HEADER_ONLY 1
#endif
#ifdef CGAL_HEADER_ONLY #ifdef CGAL_HEADER_ONLY
# define CGAL_NO_AUTOLINK 1 # define CGAL_NO_AUTOLINK 1
#endif #endif
@ -132,7 +137,7 @@
// workaround for the bug https://svn.boost.org/trac10/ticket/12534 // workaround for the bug https://svn.boost.org/trac10/ticket/12534
// That bug was introduced in Boost 1.62 and fixed in 1.63. // That bug was introduced in Boost 1.62 and fixed in 1.63.
#if BOOST_VERSION >= 106200 && BOOSTS_VERSION < 106300 #if BOOST_VERSION >= 106200 && BOOST_VERSION < 106300
# include <boost/container/flat_map.hpp> # include <boost/container/flat_map.hpp>
#endif #endif
@ -361,8 +366,6 @@
# define CGAL_BIG_ENDIAN # define CGAL_BIG_ENDIAN
# elif BOOST_ENDIAN_LITTLE_BYTE # elif BOOST_ENDIAN_LITTLE_BYTE
# define CGAL_LITTLE_ENDIAN # define CGAL_LITTLE_ENDIAN
# else
# error Unknown endianness
# endif # endif
#elif defined (__GLIBC__) #elif defined (__GLIBC__)
# include <endian.h> # include <endian.h>
@ -370,8 +373,6 @@
# define CGAL_LITTLE_ENDIAN # define CGAL_LITTLE_ENDIAN
# elif (__BYTE_ORDER == __BIG_ENDIAN) # elif (__BYTE_ORDER == __BIG_ENDIAN)
# define CGAL_BIG_ENDIAN # define CGAL_BIG_ENDIAN
# else
# error Unknown endianness
# endif # endif
#elif defined(__sparc) || defined(__sparc__) \ #elif defined(__sparc) || defined(__sparc__) \
|| defined(_POWER) || defined(__powerpc__) \ || defined(_POWER) || defined(__powerpc__) \
@ -385,11 +386,19 @@
|| defined(_M_IX86) || defined(_M_IA64) \ || defined(_M_IX86) || defined(_M_IA64) \
|| defined(_M_ALPHA) || defined(_WIN64) || defined(_M_ALPHA) || defined(_WIN64)
# define CGAL_LITTLE_ENDIAN # define CGAL_LITTLE_ENDIAN
#else
# error Unknown endianness
#endif #endif
#if ! defined(CGAL_LITTLE_ENDIAN) && ! defined(CGAL_BIG_ENDIAN)
# ifdef CGAL_DEFAULT_IS_LITTLE_ENDIAN
# if CGAL_DEFAULT_IS_LITTLE_ENDIAN
# define CGAL_LITTLE_ENDIAN
# else
# define CGAL_BIG_ENDIAN
# endif
# else
# error Unknown endianness: Define CGAL_DEFAULT_IS_LITTLE_ENDIAN to 1 for little endian and to 0 for big endian.
# endif
#endif
// Symbolic constants to tailor inlining. Inlining Policy. // Symbolic constants to tailor inlining. Inlining Policy.
// ======================================================= // =======================================================
#ifndef CGAL_MEDIUM_INLINE #ifndef CGAL_MEDIUM_INLINE
@ -550,7 +559,7 @@ using std::max;
# define CGAL_NORETURN __attribute__ ((__noreturn__)) # define CGAL_NORETURN __attribute__ ((__noreturn__))
#elif defined (_MSC_VER) #elif defined (_MSC_VER)
# define CGAL_NORETURN __declspec(noreturn) # define CGAL_NORETURN __declspec(noreturn)
#else #else
# define CGAL_NORETURN # define CGAL_NORETURN
#endif #endif

View File

@ -25,11 +25,11 @@
#ifndef CGAL_VERSION_H #ifndef CGAL_VERSION_H
#define CGAL_VERSION_H #define CGAL_VERSION_H
#define CGAL_VERSION 5.0-beta1 #define CGAL_VERSION 5.0-beta2
#define CGAL_VERSION_NR 1050000910 #define CGAL_VERSION_NR 1050000920
#define CGAL_SVN_REVISION 99999 #define CGAL_SVN_REVISION 99999
#define CGAL_GIT_HASH abcdef #define CGAL_GIT_HASH abcdef
#define CGAL_RELEASE_DATE 20190812 #define CGAL_RELEASE_DATE 20190930
#include <CGAL/version_macros.h> #include <CGAL/version_macros.h>

View File

@ -0,0 +1 @@
set(CGAL_ROOT @CMAKE_INSTALL_PREFIX@)

View File

@ -43,15 +43,17 @@ if(BRANCH_BUILD)
endif() endif()
endforeach() endforeach()
else() else()
set(CGAL_ROOT ${CGAL_CONFIG_DIR}) include(${CGAL_CONFIG_DIR}/CGALConfig-installation-dirs.cmake OPTIONAL RESULT_VARIABLE _has_installation_dirs)
get_filename_component(CGAL_ROOT "${CGAL_ROOT}" DIRECTORY) if(NOT _has_installation_dirs)
if(NOT EXISTS ${CGAL_ROOT}/include/CGAL/config.h) set(CGAL_ROOT ${CGAL_CONFIG_DIR})
get_filename_component(CGAL_ROOT "${CGAL_ROOT}" DIRECTORY) get_filename_component(CGAL_ROOT "${CGAL_ROOT}" DIRECTORY)
if(NOT EXISTS ${CGAL_ROOT}/include/CGAL/config.h)
get_filename_component(CGAL_ROOT "${CGAL_ROOT}" DIRECTORY)
endif()
if(NOT EXISTS ${CGAL_ROOT}/include/CGAL/config.h)
get_filename_component(CGAL_ROOT "${CGAL_ROOT}" DIRECTORY)
endif()
endif() endif()
if(NOT EXISTS ${CGAL_ROOT}/include/CGAL/config.h)
get_filename_component(CGAL_ROOT "${CGAL_ROOT}" DIRECTORY)
endif()
# not BRANCH_BUILD: it can be an installed CGAL, or the tarball layout # not BRANCH_BUILD: it can be an installed CGAL, or the tarball layout
if(EXISTS ${CGAL_CONFIG_DIR}/CGAL_add_test.cmake) if(EXISTS ${CGAL_CONFIG_DIR}/CGAL_add_test.cmake)
# installed CGAL # installed CGAL
@ -95,7 +97,9 @@ endforeach()
set(CGALConfig_all_targets_are_defined TRUE) set(CGALConfig_all_targets_are_defined TRUE)
foreach(cgal_lib ${CGAL_LIBRARIES}) foreach(cgal_lib ${CGAL_LIBRARIES})
if(NOT TARGET CGAL::${cgal_lib}) if(TARGET CGAL::${cgal_lib})
set(${cgal_lib}_FOUND TRUE)
else()
set(CGALConfig_all_targets_are_defined FALSE) set(CGALConfig_all_targets_are_defined FALSE)
endif() endif()
endforeach() endforeach()
@ -139,9 +143,6 @@ foreach(cgal_lib ${CGAL_LIBRARIES})
if(NOT TARGET CGAL::${cgal_lib}) if(NOT TARGET CGAL::${cgal_lib})
add_library(CGAL::${cgal_lib} ALIAS ${cgal_lib}) add_library(CGAL::${cgal_lib} ALIAS ${cgal_lib})
endif() endif()
if(${cgal_lib} STREQUAL CGAL)
target_compile_definitions(CGAL INTERFACE CGAL_HEADER_ONLY=1)
endif()
CGAL_setup_target_dependencies(${cgal_lib} INTERFACE) CGAL_setup_target_dependencies(${cgal_lib} INTERFACE)
endif() endif()
endforeach() endforeach()

View File

@ -10,8 +10,8 @@ endif()
CGAL_setup_CGAL_dependencies(CGAL ${keyword}) CGAL_setup_CGAL_dependencies(CGAL ${keyword})
if(CGAL_HEADER_ONLY) if(NOT CGAL_HEADER_ONLY)
target_compile_definitions(CGAL INTERFACE CGAL_HEADER_ONLY=1) target_compile_definitions(CGAL INTERFACE CGAL_NOT_HEADER_ONLY=1)
endif() endif()
if(NOT CGAL_DISABLE_GMP) if(NOT CGAL_DISABLE_GMP)

View File

@ -127,29 +127,30 @@ struct DefaultDrawingFunctorLCC
} }
}; };
template<class LCC, class Kernel, int dim=LCC::ambient_dimension> template<class LCC, class Local_kernel, int dim=LCC::ambient_dimension>
struct LCC_geom_utils; struct LCC_geom_utils;
template<class LCC, class Kernel> template<class LCC, class Local_kernel>
struct LCC_geom_utils<LCC, Kernel, 3> struct LCC_geom_utils<LCC, Local_kernel, 3>
{ {
static typename Kernel::Vector_3 static typename Local_kernel::Vector_3
get_vertex_normal(const LCC& lcc, typename LCC::Dart_const_handle dh) get_vertex_normal(const LCC& lcc, typename LCC::Dart_const_handle dh)
{ {
typename Kernel::Vector_3 n = internal::Geom_utils<typename LCC::Traits>:: typename Local_kernel::Vector_3 n = internal::Geom_utils
<typename LCC::Traits, Local_kernel>::
get_local_vector(CGAL::compute_normal_of_cell_0<LCC>(lcc,dh)); get_local_vector(CGAL::compute_normal_of_cell_0<LCC>(lcc,dh));
n = n/(CGAL::sqrt(n*n)); n = n/(CGAL::sqrt(n*n));
return n; return n;
} }
}; };
template<class LCC, class Kernel> template<class LCC, class Local_kernel>
struct LCC_geom_utils<LCC, Kernel, 2> struct LCC_geom_utils<LCC, Local_kernel, 2>
{ {
static typename Kernel::Vector_3 static typename Local_kernel::Vector_3
get_vertex_normal(const LCC&, typename LCC::Dart_const_handle) get_vertex_normal(const LCC&, typename LCC::Dart_const_handle)
{ {
typename Kernel::Vector_3 n=CGAL::NULL_VECTOR; typename Local_kernel::Vector_3 n=CGAL::NULL_VECTOR;
return n; return n;
} }
}; };

View File

@ -23,13 +23,13 @@ LC_CTYPE=en_US.UTF-8
# The script also updates the manual tools. # The script also updates the manual tools.
# "master" alone # "master" alone
0 21 * * Sun cd $HOME/CGAL/create_internal_release && /usr/bin/time $HOME/bin/create_release $HOME/CGAL/branches/master.git --public --do-it || echo ERROR 0 21 * * Sun cd $HOME/CGAL/create_internal_release && /usr/bin/time $HOME/bin/create_release $HOME/CGAL/branches/master.git --public --do-it --beta 2 || echo ERROR
# "integration" # "integration"
0 21 * * Mon,Tue,Wed,Thu cd $HOME/CGAL/create_internal_release && /usr/bin/time $HOME/bin/create_release $HOME/CGAL/branches/integration.git $HOME/CGAL/branches/empty-dir --do-it || echo ERROR 0 21 * * Mon,Tue,Wed,Thu,Fri cd $HOME/CGAL/create_internal_release && /usr/bin/time $HOME/bin/create_release $HOME/CGAL/branches/integration.git $HOME/CGAL/branches/empty-dir --do-it || echo ERROR
# from branch 4.14 # from branch 4.14
0 21 * * Sat cd $HOME/CGAL/create_internal_release-4.14-branch && /usr/bin/time $HOME/bin/create_release $HOME/CGAL/branches/CGAL-4.14-branch.git --public --do-it || echo ERROR 0 21 * * Sat cd $HOME/CGAL/create_internal_release-4.14-branch && /usr/bin/time $HOME/bin/create_release $HOME/CGAL/branches/CGAL-4.14-branch.git --public --do-it || echo ERROR
# from branch 4.13 # from branch 4.13
0 21 * * Fri cd $HOME/CGAL/create_internal_release-4.13-branch && /usr/bin/time $HOME/bin/create_release $HOME/CGAL/branches/CGAL-4.13-branch.git --public --do-it || echo ERROR #0 21 * * Fri cd $HOME/CGAL/create_internal_release-4.13-branch && /usr/bin/time $HOME/bin/create_release $HOME/CGAL/branches/CGAL-4.13-branch.git --public --do-it || echo ERROR
# from branch 4.12 # from branch 4.12
#0 21 * * Sat cd $HOME/CGAL/create_internal_release-4.12-branch && /usr/bin/time $HOME/bin/create_release $HOME/CGAL/branches/CGAL-4.12-branch.git --public --do-it || echo ERROR #0 21 * * Sat cd $HOME/CGAL/create_internal_release-4.12-branch && /usr/bin/time $HOME/bin/create_release $HOME/CGAL/branches/CGAL-4.12-branch.git --public --do-it || echo ERROR
# from branch 4.11 # from branch 4.11

View File

@ -1,52 +1,109 @@
Subject: CGAL 4.14 Beta 1 Released, Computational Geometry Algorithms Library Subject: CGAL 5.0 Beta 1 Released, Computational Geometry Algorithms Library
Content-Type: text/plain; charset="utf-8" Content-Type: text/plain; charset="utf-8"
Body: Body:
The CGAL Open Source Project is pleased to announce the release 4.14 Beta 1 The CGAL Open Source Project is pleased to announce the release 5.0 Beta 1
of CGAL, the Computational Geometry Algorithms Library. of CGAL, the Computational Geometry Algorithms Library.
CGAL version 4.14 Beta 1 is a public testing release. It should provide CGAL version 5.0 Beta 1 is a public testing release. It should provide
a solid ground to report bugs that need to be tackled before the a solid ground to report bugs that need to be tackled before the
release of the final version of CGAL 4.14 in September. release of the final version of CGAL 5.0 in October.
CGAL 5.0 is the first release of CGAL that requires a C++ compiler
with the support of C++14 or later. The new list of supported
compilers is:
- Visual C++ 14.0 (from Visual Studio 2015 Update 3) or later,
- Gnu g++ 6.3 or later (on Linux or MacOS),
- LLVM Clang version 8.0 or later (on Linux or MacOS), and
- Apple Clang compiler versions 7.0.2 and 10.0.1 (on MacOS).
Since CGAL 4.9, CGAL can be used as a header-only library, with
dependencies. Since CGAL 5.0, that is now the default, unless
specified differently in the (optional) CMake configuration.
Besides fixes and general enhancement to existing packages, the following Besides fixes and general enhancement to existing packages, the following
has changed since CGAL 4.13: has changed since CGAL 4.14:
### 2D Periodic Hyperbolic Triangulations (new package) Polygonal Surface Reconstruction (new package)
- This package allows the computation of Delaunay triangulations of - This package provides a method for piecewise planar object
the Bolza surface. The Bolza surface is the most symmetric reconstruction from point clouds. The method takes as input an
hyperbolic surface of genus 2. Its fundamental domain is the unordered point set sampled from a piecewise planar object and
regular hyperbolic octagon with angles π/4 centered at the origin outputs a compact and watertight surface mesh interpolating the
of the Poincaré disk. Triangulations of the Bolza surface can be input point set. The method assumes that all necessary major planes
seen as triangulations of the hyperbolic plane that are periodic are provided (or can be extracted from the input point set using the
in the four directions defined by the sides of this regular shape detection method described in Point Set Shape Detection, or
octagon. any other alternative methods).The method can handle arbitrary
piecewise planar objects and is capable of recovering sharp features
### 2D Hyperbolic Triangulations (new package) and is robust to noise and outliers. See also the associated blog
entry:
- This package allows the computation of Delaunay Triangulations of
sets of points in the Poincaré disk, which is one of the https://www.cgal.org/2019/08/05/Polygonal_surface_reconstruction/
conformal models for the hyperbolic plane.
### The Heat Method (new package)
- This package provides an algorithm that solves the single- or
multiple-source shortest path problem by returning an
approximation of the geodesic distance for all vertices of a
triangle mesh to the closest vertex in a given set of source
vertices.
### Triangulated Surface Mesh Approximation (new package)
- This package implements the Variational Shape Approximation method
to approximate an input surface triangle mesh by a simpler surface
triangle mesh.
See https://www.cgal.org/2019/03/04/cgal414-beta1/ for a complete list of Shape Detection (major changes)
- BREAKING CHANGE: The concept ShapeDetectionTraits has been renamed
to EfficientRANSACTraits.
- BREAKING CHANGE: The Shape_detection_3 namespace has been renamed to
Shape_detection.
- Added a new, generic implementation of region growing. This enables
for example applying region growing to inputs such as 2D and 3D
point sets, or models of the FaceGraph concept. Learn more about
this new algorithm with this blog entry:
https://www.cgal.org/2019/07/30/Shape_detection/
dD Geometry Kernel
- A new exact kernel, Epeck_d, is now available.
2D and 3D Triangulations
- BREAKING CHANGE: Several deprecated functions and classes have been
removed. See the full list of breaking changes in the release
notes.
- BREAKING CHANGE: The constructor and the insert() function of
CGAL::Triangulation_2 or CGAL::Triangulation_3 which take a range
of points as argument are now guaranteed to insert the points
following the order of InputIterator. Note that this change only
affects the base class CGAL::Triangulation_[23] and not any
derived class, such as CGAL::Delaunay_triangulation_[23].
Polygon Mesh Processing
- Introduced a wide range of new functions related to location of
queries on a triangle mesh, such as
CGAL::Polygon_mesh_processing::locate(Point, Mesh). The location of
a point on a triangle mesh is expressed as the pair of a face and
the barycentric coordinates of the point in this face, enabling
robust manipulation of locations (for example, intersections of two
3D segments living within the same face).
- Added the mesh smoothing function smooth_mesh(), which can be used
to improve the quality of triangle elements based on various
geometric characteristics.
- Added the shape smoothing function smooth_shape(), which can be used
to smooth the surface of a triangle mesh, using the mean curvature
flow to perform noise removal.
Point Set Processing
- BREAKING CHANGE: the API using iterators and overloads for optional
parameters (deprecated since CGAL 4.12) has been removed. The
current (and now only) API uses ranges and Named Parameters.
See https://www.cgal.org/2019/09/30/cgal50-beta1/ for a complete list of
changes. changes.

View File

@ -1 +1 @@
CGAL-5.0-beta1 CGAL-5.0-beta2

View File

@ -86,10 +86,11 @@
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
# pragma warning(push) # pragma warning(push)
# pragma warning(disable:4146 4244 4267 4800) # pragma warning(disable:4146 4244 4267 4702 4800)
// warning on - applied on unsigned number // warning on - applied on unsigned number
// conversion with loss of data // conversion with loss of data
// conversion with loss of data // conversion with loss of data
// unreachable code
// int to bool performance // int to bool performance
#endif #endif

View File

@ -28,4 +28,6 @@ EXPAND_AS_DEFINED = CGAL_PMP_NP_TEMPLATE_PARAMETERS \
EXCLUDE = ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Polygon_mesh_processing/internal EXCLUDE = ${CGAL_PACKAGE_INCLUDE_DIR}/CGAL/Polygon_mesh_processing/internal
EXCLUDE_SYMBOLS += experimental EXCLUDE_SYMBOLS += experimental
HTML_EXTRA_FILES = ${CGAL_PACKAGE_DOC_DIR}/fig/selfintersections.jpg HTML_EXTRA_FILES = ${CGAL_PACKAGE_DOC_DIR}/fig/selfintersections.jpg \
${CGAL_PACKAGE_DOC_DIR}/fig/mesh_smoothing.png \
${CGAL_PACKAGE_DOC_DIR}/fig/shape_smoothing.png

View File

@ -70,7 +70,7 @@
\cgalPkgPicture{hole_filling_ico.png} \cgalPkgPicture{hole_filling_ico.png}
\cgalPkgSummaryBegin \cgalPkgSummaryBegin
\cgalPkgAuthor{Sébastien Loriot, Jane Tournois, Ilker %O. Yaz} \cgalPkgAuthor{Sébastien Loriot, Mael Rouxel-Labbé, Jane Tournois, Ilker %O. Yaz}
\cgalPkgDesc{This package provides \cgalPkgDesc{This package provides
a collection of methods and classes for polygon mesh processing, a collection of methods and classes for polygon mesh processing,
ranging from basic operations on simplices, to complex geometry processing algorithms.} ranging from basic operations on simplices, to complex geometry processing algorithms.}

View File

@ -4,7 +4,7 @@ namespace CGAL {
\anchor Chapter_PolygonMeshProcessing \anchor Chapter_PolygonMeshProcessing
\cgalAutoToc \cgalAutoToc
\authors Sébastien Loriot, Jane Tournois, Ilker %O. Yaz \authors Sébastien Loriot, Mael Rouxel-Labbé, Jane Tournois, Ilker %O. Yaz
\image html neptun_head.jpg \image html neptun_head.jpg
\image latex neptun_head.jpg \image latex neptun_head.jpg
@ -874,6 +874,12 @@ and the number of surface patches that are separated by these edges.
A first version of this package was started by Ilker %O. Yaz and Sébastien Loriot. A first version of this package was started by Ilker %O. Yaz and Sébastien Loriot.
Jane Tournois worked on the finalization of the API, code, and documentation. Jane Tournois worked on the finalization of the API, code, and documentation.
A prototype of mesh and shape smoothing was developed during the 2017 edition of the Google Summer of Code
by Konstantinos Katrioplas, under supervision of Jane Tournois. It was finalized by Mael Rouxel-Labbé and
integrated in \cgal 5.0.
Functionalities related to mesh and polygon soup reparation have been introduced steadily over multiple versions
since \cgal 4.10, in joint work between Sébastien Loriot and Mael Rouxel-Labbé.
*/ */
} /* namespace CGAL */ } /* namespace CGAL */

View File

@ -33,6 +33,16 @@
#include <CGAL/Polygon_mesh_processing/internal/named_params_helper.h> #include <CGAL/Polygon_mesh_processing/internal/named_params_helper.h>
#ifdef DOXYGEN_RUNNING
#define CGAL_PMP_NP_TEMPLATE_PARAMETERS NamedParameters
#define CGAL_PMP_NP_CLASS NamedParameters
#endif
#ifdef DOXYGEN_RUNNING
#define CGAL_PMP_NP_TEMPLATE_PARAMETERS NamedParameters
#define CGAL_PMP_NP_CLASS NamedParameters
#endif
namespace CGAL { namespace CGAL {
namespace Polygon_mesh_processing { namespace Polygon_mesh_processing {

View File

@ -34,6 +34,11 @@
#include <CGAL/boost/graph/Euler_operations.h> #include <CGAL/boost/graph/Euler_operations.h>
#include <vector> #include <vector>
#ifdef DOXYGEN_RUNNING
#define CGAL_PMP_NP_TEMPLATE_PARAMETERS NamedParameters
#define CGAL_PMP_NP_CLASS NamedParameters
#endif
namespace CGAL { namespace CGAL {
namespace Polygon_mesh_processing { namespace Polygon_mesh_processing {
namespace extrude_impl{ namespace extrude_impl{

View File

@ -69,18 +69,18 @@ namespace internal{
const PolygonMesh& pmesh, const PolygonMesh& pmesh,
const NamedParameters& np) const NamedParameters& np)
{ {
using parameters::choose_parameter;
using parameters::get_parameter; using parameters::get_parameter;
CGAL_assertion(halfedge(v_max, pmesh)!=boost::graph_traits<PolygonMesh>::null_halfedge()); CGAL_assertion(halfedge(v_max, pmesh)!=boost::graph_traits<PolygonMesh>::null_halfedge());
//VertexPointMap //VertexPointMap
typedef typename GetVertexPointMap<PolygonMesh, NamedParameters>::const_type VPMap; typedef typename GetVertexPointMap<PolygonMesh, NamedParameters>::const_type VPMap;
VPMap vpmap = choose_parameter(get_parameter(np, internal_np::vertex_point), VPMap vpmap = CGAL::parameters::choose_parameter(get_parameter(np, internal_np::vertex_point),
get_const_property_map(vertex_point, pmesh)); get_const_property_map(vertex_point, pmesh));
//Kernel //Kernel
typedef typename GetGeomTraits<PolygonMesh, NamedParameters>::type GT; typedef typename GetGeomTraits<PolygonMesh, NamedParameters>::type GT;
GT gt = choose_parameter(get_parameter(np, internal_np::geom_traits), GT()); GT gt = CGAL::parameters::choose_parameter(get_parameter(np, internal_np::geom_traits), GT());
//among the incoming edges of `v_max`, find one edge `e` with the minimal slope //among the incoming edges of `v_max`, find one edge `e` with the minimal slope
typedef typename boost::graph_traits<PolygonMesh>::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits<PolygonMesh>::halfedge_descriptor halfedge_descriptor;
@ -182,16 +182,16 @@ bool is_outward_oriented(const PolygonMesh& pmesh,
if (faces(pmesh).first == faces(pmesh).second) if (faces(pmesh).first == faces(pmesh).second)
return true; return true;
using parameters::choose_parameter;
using parameters::get_parameter; using parameters::get_parameter;
//VertexPointMap //VertexPointMap
typedef typename GetVertexPointMap<PolygonMesh, NamedParameters>::const_type VPMap; typedef typename GetVertexPointMap<PolygonMesh, NamedParameters>::const_type VPMap;
VPMap vpmap = choose_parameter(get_parameter(np, internal_np::vertex_point), VPMap vpmap = CGAL::parameters::choose_parameter(get_parameter(np, internal_np::vertex_point),
get_const_property_map(vertex_point, pmesh)); get_const_property_map(vertex_point, pmesh));
//Kernel //Kernel
typedef typename GetGeomTraits<PolygonMesh, NamedParameters>::type GT; typedef typename GetGeomTraits<PolygonMesh, NamedParameters>::type GT;
GT gt = choose_parameter(get_parameter(np, internal_np::geom_traits), GT()); GT gt = CGAL::parameters::choose_parameter(get_parameter(np, internal_np::geom_traits), GT());
//find the vertex with maximal z coordinate //find the vertex with maximal z coordinate
internal::Compare_vertex_points_z_3<GT, VPMap> less_z(vpmap, gt); internal::Compare_vertex_points_z_3<GT, VPMap> less_z(vpmap, gt);
@ -482,16 +482,15 @@ void orient(TriangleMesh& tm, const NamedParameters& np)
CGAL_assertion(is_valid_polygon_mesh(tm)); CGAL_assertion(is_valid_polygon_mesh(tm));
CGAL_assertion(is_closed(tm)); CGAL_assertion(is_closed(tm));
using parameters::choose_parameter;
using parameters::get_parameter; using parameters::get_parameter;
bool orient_outward = choose_parameter( bool orient_outward = CGAL::parameters::choose_parameter(
get_parameter(np, internal_np::outward_orientation),true); get_parameter(np, internal_np::outward_orientation),true);
Vpm vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), Vpm vpm = CGAL::parameters::choose_parameter(get_parameter(np, internal_np::vertex_point),
get_const_property_map(boost::vertex_point, tm)); get_const_property_map(boost::vertex_point, tm));
Fid_map fid_map = choose_parameter(get_parameter(np, internal_np::face_index), Fid_map fid_map = CGAL::parameters::choose_parameter(get_parameter(np, internal_np::face_index),
get_const_property_map(boost::face_index, tm)); get_const_property_map(boost::face_index, tm));
std::vector<std::size_t> face_cc(num_faces(tm), std::size_t(-1)); std::vector<std::size_t> face_cc(num_faces(tm), std::size_t(-1));
@ -589,16 +588,16 @@ void orient_to_bound_a_volume(TriangleMesh& tm,
if (!is_closed(tm)) return; if (!is_closed(tm)) return;
if (!is_triangle_mesh(tm)) return; if (!is_triangle_mesh(tm)) return;
using parameters::choose_parameter;
using parameters::get_parameter; using parameters::get_parameter;
bool orient_outward = choose_parameter( bool orient_outward = CGAL::parameters::choose_parameter(
get_parameter(np, internal_np::outward_orientation),true); get_parameter(np, internal_np::outward_orientation),true);
Vpm vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), Vpm vpm = CGAL::parameters::choose_parameter(get_parameter(np, internal_np::vertex_point),
get_const_property_map(boost::vertex_point, tm)); get_const_property_map(boost::vertex_point, tm));
Fid_map fid_map = choose_parameter(get_parameter(np, internal_np::face_index), Fid_map fid_map = CGAL::parameters::choose_parameter(get_parameter(np, internal_np::face_index),
get_const_property_map(boost::face_index, tm)); get_const_property_map(boost::face_index, tm));
std::vector<std::size_t> face_cc(num_faces(tm), std::size_t(-1)); std::vector<std::size_t> face_cc(num_faces(tm), std::size_t(-1));

View File

@ -62,6 +62,11 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#ifdef DOXYGEN_RUNNING
#define CGAL_PMP_NP_TEMPLATE_PARAMETERS NamedParameters
#define CGAL_PMP_NP_CLASS NamedParameters
#endif
namespace CGAL{ namespace CGAL{
namespace Polygon_mesh_processing { namespace Polygon_mesh_processing {
namespace debug{ namespace debug{

View File

@ -575,7 +575,7 @@ std::size_t merge_duplicate_points_in_polygon_soup(PointRange& points,
const std::size_t removed_points_n = ini_points_n - points.size(); const std::size_t removed_points_n = ini_points_n - points.size();
#ifdef CGAL_PMP_REPAIR_POLYGON_SOUP_VERBOSE_PP #ifdef CGAL_PMP_REPAIR_POLYGON_SOUP_VERBOSE
std::cout << "Removed (merged) " << removed_points_n << " duplicate points" << std::endl; std::cout << "Removed (merged) " << removed_points_n << " duplicate points" << std::endl;
#endif #endif

View File

@ -34,6 +34,11 @@
#include <CGAL/property_map.h> #include <CGAL/property_map.h>
#ifdef DOXYGEN_RUNNING
#define CGAL_PMP_NP_TEMPLATE_PARAMETERS NamedParameters
#define CGAL_PMP_NP_CLASS NamedParameters
#endif
namespace CGAL { namespace CGAL {
namespace Polygon_mesh_processing { namespace Polygon_mesh_processing {

View File

@ -39,6 +39,11 @@
#include <sstream> #include <sstream>
#endif #endif
#ifdef DOXYGEN_RUNNING
#define CGAL_PMP_NP_TEMPLATE_PARAMETERS NamedParameters
#define CGAL_PMP_NP_CLASS NamedParameters
#endif
namespace CGAL { namespace CGAL {
namespace Polygon_mesh_processing { namespace Polygon_mesh_processing {

View File

@ -39,6 +39,11 @@
#include <vector> #include <vector>
#ifdef DOXYGEN_RUNNING
#define CGAL_PMP_NP_TEMPLATE_PARAMETERS NamedParameters
#define CGAL_PMP_NP_CLASS NamedParameters
#endif
namespace CGAL { namespace CGAL {
namespace Polygon_mesh_processing { namespace Polygon_mesh_processing {

View File

@ -331,6 +331,10 @@ class Point_set_item_classification : public Item_classification_base
std::vector<int> indices (m_points->point_set()->size(), -1); std::vector<int> indices (m_points->point_set()->size(), -1);
m_label_probabilities.clear(); m_label_probabilities.clear();
m_label_probabilities.resize (m_labels.size());
for (std::size_t i = 0; i < m_label_probabilities.size(); ++ i)
m_label_probabilities[i].resize (m_points->point_set()->size(), -1);
if (method == 0) if (method == 0)
CGAL::Classification::classify<Concurrency_tag> (*(m_points->point_set()), CGAL::Classification::classify<Concurrency_tag> (*(m_points->point_set()),
m_labels, classifier, m_labels, classifier,

View File

@ -2,6 +2,7 @@
#include "Scene_polygon_soup_item.h" #include "Scene_polygon_soup_item.h"
#include "Scene_points_with_normal_item.h" #include "Scene_points_with_normal_item.h"
#include <CGAL/Three/Three.h> #include <CGAL/Three/Three.h>
#include <CGAL/Polygon_mesh_processing/repair.h>
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h> #include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>
@ -25,17 +26,17 @@ class Polyhedron_demo_off_plugin :
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "off_io_plugin.json") Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.IOPluginInterface/1.90" FILE "off_io_plugin.json")
public: public:
bool isDefaultLoader(const Scene_item *item) const bool isDefaultLoader(const Scene_item *item) const
{ {
if(qobject_cast<const Scene_surface_mesh_item*>(item) if(qobject_cast<const Scene_surface_mesh_item*>(item)
|| qobject_cast<const Scene_polygon_soup_item*>(item)) || qobject_cast<const Scene_polygon_soup_item*>(item))
return true; return true;
return false; return false;
} }
bool isDefaultLoader(const QString& name) const bool isDefaultLoader(const QString& name) const
{ {
if(name == QString("off")) if(name == QString("off"))
return true; return true;
return false; return false;
} }
QString name() const { return "off_plugin"; } QString name() const { return "off_plugin"; }
@ -44,7 +45,7 @@ public:
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true); QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene=true);
CGAL::Three::Scene_item* load_off(QFileInfo fileinfo); CGAL::Three::Scene_item* load_off(QFileInfo fileinfo);
CGAL::Three::Scene_item* load_obj(QFileInfo fileinfo); CGAL::Three::Scene_item* load_obj(QFileInfo fileinfo);
bool canSave(const CGAL::Three::Scene_item*); bool canSave(const CGAL::Three::Scene_item*);
bool save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& ); bool save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& );
}; };
@ -55,7 +56,7 @@ bool Polyhedron_demo_off_plugin::canLoad(QFileInfo) const {
QList<Scene_item*> Polyhedron_demo_off_plugin:: QList<Scene_item*> Polyhedron_demo_off_plugin::
load(QFileInfo fileinfo, bool& ok, bool add_to_scene) { load(QFileInfo fileinfo, bool& ok, bool add_to_scene) {
if(fileinfo.size() == 0) if(fileinfo.size() == 0)
{ {
CGAL::Three::Three::warning( tr("The file you are trying to load is empty.")); CGAL::Three::Three::warning( tr("The file you are trying to load is empty."));
@ -108,10 +109,10 @@ Polyhedron_demo_off_plugin::load_off(QFileInfo fileinfo) {
std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl; std::cerr << "Error! Cannot open file " << (const char*)fileinfo.filePath().toUtf8() << std::endl;
return NULL; return NULL;
} }
CGAL::File_scanner_OFF scanner( in, false); CGAL::File_scanner_OFF scanner( in, false);
// Try to read .off in a point set // Try to read .off in a point set
if (scanner.size_of_facets() == 0) if (scanner.size_of_facets() == 0)
{ {
@ -124,10 +125,10 @@ Polyhedron_demo_off_plugin::load_off(QFileInfo fileinfo) {
delete item; delete item;
return 0; return 0;
} }
return item; return item;
} }
in.seekg(0); in.seekg(0);
// Try to read .off in a surface_mesh // Try to read .off in a surface_mesh
SMesh *surface_mesh = new SMesh(); SMesh *surface_mesh = new SMesh();
@ -181,6 +182,19 @@ Polyhedron_demo_off_plugin::load_off(QFileInfo fileinfo) {
tr("%1 isolated vertices found") tr("%1 isolated vertices found")
.arg(item->getNbIsolatedvertices())); .arg(item->getNbIsolatedvertices()));
} }
typedef boost::function_output_iterator<CGAL::internal::Throw_at_output> OutputIterator;
try{
CGAL::Polygon_mesh_processing::non_manifold_vertices(*surface_mesh, OutputIterator());
}
catch( CGAL::internal::Throw_at_output::Throw_at_output_exception& )
{
QApplication::restoreOverrideCursor();
QMessageBox::warning((QWidget*)NULL,
tr("Non Manifold Vertices"),
tr("Non-manifold vertices have been found"));
}
if(item->isItemMulticolor()) if(item->isItemMulticolor())
item->computeItemColorVectorAutomatically(true); item->computeItemColorVectorAutomatically(true);
return item; return item;
@ -218,9 +232,9 @@ save(QFileInfo fileinfo,QList<CGAL::Three::Scene_item*>& items)
// This plugin supports point sets, surface_meshes and polygon soups // This plugin supports point sets, surface_meshes and polygon soups
const Scene_points_with_normal_item* points_item = const Scene_points_with_normal_item* points_item =
qobject_cast<const Scene_points_with_normal_item*>(item); qobject_cast<const Scene_points_with_normal_item*>(item);
const Scene_surface_mesh_item* sm_item = const Scene_surface_mesh_item* sm_item =
qobject_cast<const Scene_surface_mesh_item*>(item); qobject_cast<const Scene_surface_mesh_item*>(item);
const Scene_polygon_soup_item* soup_item = const Scene_polygon_soup_item* soup_item =
qobject_cast<const Scene_polygon_soup_item*>(item); qobject_cast<const Scene_polygon_soup_item*>(item);
if(!sm_item && !soup_item && !points_item) if(!sm_item && !soup_item && !points_item)

View File

@ -278,18 +278,37 @@ private:
QString name(y_tag) const { return tr("Y Slice for %2").arg(name_); } QString name(y_tag) const { return tr("Y Slice for %2").arg(name_); }
QString name(z_tag) const { return tr("Z Slice for %2").arg(name_); } QString name(z_tag) const { return tr("Z Slice for %2").arg(name_); }
double compute_maxDim() const //according to the tag, a,b,c dim change but not the scale. We look for the max dimension of the whole image.
//A high scale factor will often go with a low dimesion, to compensate it. So we don't want a max being the
//higher scale * the higher dim, hence the tag specialisation.
//TODO: set the scale factors according to the dimensipon to avoid doing that.
double compute_maxDim(x_tag) const
{ {
double ax((adim_ - 1) * xscale_), ay((adim_ - 1) * yscale_), az((adim_ - 1) * zscale_), double max_a((adim_ - 1) * yscale_),
bx((bdim_ - 1) * xscale_), by((bdim_ - 1) * yscale_), bz((bdim_ - 1) * zscale_), max_b((bdim_ - 1) * zscale_),
cx((cdim_ - 1) * xscale_), cy((cdim_ - 1) * yscale_), cz((cdim_ - 1) * zscale_); max_c((cdim_ - 1) * xscale_);
double max_a = (std::max)((std::max)(ax, ay), az);
double max_b = (std::max)((std::max)(bx, by), bz);
double max_c = (std::max)((std::max)(cx, cy), cz);
return (std::max)((std::max)(max_a, max_b), max_c); return (std::max)((std::max)(max_a, max_b), max_c);
} }
double compute_maxDim(y_tag) const
{
double max_a((adim_ - 1) * xscale_),
max_b((bdim_ - 1) * zscale_),
max_c((cdim_ - 1) * yscale_);
return (std::max)((std::max)(max_a, max_b), max_c);
}
double compute_maxDim(z_tag) const
{
double max_a((adim_ - 1) * xscale_),
max_b((bdim_ - 1) * yscale_),
max_c((cdim_ - 1) * zscale_);
return (std::max)((std::max)(max_a, max_b), max_c);
}
void drawRectangle(x_tag, bool is_loop) const { void drawRectangle(x_tag, bool is_loop) const {
@ -348,20 +367,23 @@ private:
void drawSpheres(x_tag) const void drawSpheres(x_tag) const
{ {
double max_dim = compute_maxDim(); double max_dim = compute_maxDim(x_tag());
sphere_radius = max_dim / 40.0f; sphere_radius = max_dim / 40.0f;
create_flat_sphere(1.0f, v_spheres, n_spheres, 18); create_flat_sphere(1.0f, v_spheres, n_spheres, 18);
c_spheres.push_back(0.0f); c_spheres.push_back((adim_ - 1) * yscale_/2.0f + max_dim/15.0f); c_spheres.push_back(0.0f); c_spheres.push_back(0.0f); c_spheres.push_back((adim_ - 1) * yscale_/2.0f + 1.1*sphere_radius); c_spheres.push_back(0.0f);
c_spheres.push_back(0.0f); c_spheres.push_back((adim_ - 1) * yscale_ ); c_spheres.push_back((bdim_ - 1) * zscale_/2.0f + max_dim/15.0f);
c_spheres.push_back(0.0f); c_spheres.push_back((adim_ - 1) * yscale_/2.0f + max_dim/15.0f); c_spheres.push_back((bdim_ - 1 ) * zscale_); c_spheres.push_back(0.0f); c_spheres.push_back((adim_ - 1) * yscale_ ); c_spheres.push_back((bdim_ - 1) * zscale_/2.0f + 1.1*sphere_radius);
c_spheres.push_back(0.0f); c_spheres.push_back(0.0f); c_spheres.push_back((bdim_ - 1) * zscale_/2.0f + max_dim/15.0f);
c_spheres.push_back(0.0f); c_spheres.push_back((adim_ - 1) * yscale_/2.0f + 1.1*sphere_radius); c_spheres.push_back((bdim_ - 1 ) * zscale_);
c_spheres.push_back(0.0f); c_spheres.push_back(0.0f); c_spheres.push_back((bdim_ - 1) * zscale_/2.0f + 1.1*sphere_radius);
} }
void drawSpheres(y_tag) const void drawSpheres(y_tag) const
{ {
double max_dim = compute_maxDim(); double max_dim = compute_maxDim(y_tag());
sphere_radius = max_dim / 40.0f; sphere_radius = max_dim / 40.0f;
create_flat_sphere(1.0f, v_spheres, n_spheres,18); create_flat_sphere(1.0f, v_spheres, n_spheres,18);
@ -373,14 +395,14 @@ private:
void drawSpheres(z_tag) const void drawSpheres(z_tag) const
{ {
double max_dim = compute_maxDim(); double max_dim = compute_maxDim(z_tag());
sphere_radius = max_dim / 40.0f; sphere_radius = max_dim / 40.0f;
create_flat_sphere(1.0f, v_spheres, n_spheres,18); create_flat_sphere(1.0f, v_spheres, n_spheres,18);
c_spheres.push_back(0.0f); c_spheres.push_back((bdim_ - 1) * yscale_/2.0f - max_dim/15.0f); c_spheres.push_back(0.0f); c_spheres.push_back(0.0f); c_spheres.push_back((bdim_ - 1) * yscale_/2.0f - 1.1*sphere_radius); c_spheres.push_back(0.0f);
c_spheres.push_back((adim_ - 1) * xscale_/2.0f-max_dim/15.0f); c_spheres.push_back((bdim_ - 1) * yscale_); c_spheres.push_back(0.0f); c_spheres.push_back((adim_ - 1) * xscale_/2.0f-1.1*sphere_radius); c_spheres.push_back((bdim_ - 1) * yscale_); c_spheres.push_back(0.0f);
c_spheres.push_back((adim_ - 1) * xscale_); c_spheres.push_back((bdim_ - 1) * yscale_/2.0f-max_dim/15.0f); c_spheres.push_back(0.0f); c_spheres.push_back((adim_ - 1) * xscale_); c_spheres.push_back((bdim_ - 1) * yscale_/2.0f-1.1*sphere_radius); c_spheres.push_back(0.0f);
c_spheres.push_back((adim_ - 1) * xscale_/2.0f-max_dim/15.0f); c_spheres.push_back(0.0f); c_spheres.push_back(0.0f); c_spheres.push_back((adim_ - 1) * xscale_/2.0f-1.1*sphere_radius); c_spheres.push_back(0.0f); c_spheres.push_back(0.0f);
} }
CGAL::qglviewer::Constraint* setConstraint(x_tag) { CGAL::qglviewer::Constraint* setConstraint(x_tag) {
@ -544,7 +566,7 @@ void Volume_plane<T>::draw(Viewer_interface *viewer) const {
bDim() <= 1 || bDim() <= 1 ||
cDim() <=1) cDim() <=1)
return; return;
double max_dim = compute_maxDim(); double max_dim = compute_maxDim(*this);
sphere_radius = max_dim/20.0f * sphere_Slider->value()/100.0f; sphere_radius = max_dim/20.0f * sphere_Slider->value()/100.0f;
getTriangleContainer(1)->getVbo(Tc::Radius)->bind(); getTriangleContainer(1)->getVbo(Tc::Radius)->bind();
getTriangleContainer(1)->getVao(viewer)->program->setAttributeValue("radius", sphere_radius); getTriangleContainer(1)->getVao(viewer)->program->setAttributeValue("radius", sphere_radius);

View File

@ -14,25 +14,6 @@
#include <CGAL/boost/graph/helpers.h> #include <CGAL/boost/graph/helpers.h>
#include <boost/graph/filtered_graph.hpp> #include <boost/graph/filtered_graph.hpp>
template <typename G>
struct Is_border {
const G& g;
Is_border(const G& g)
: g(g)
{}
template <typename Descriptor>
bool operator()(const Descriptor& d) const {
return is_border(d,g);
}
bool operator()(typename boost::graph_traits<G>::vertex_descriptor d) const {
return is_border(d,g) != boost::none;
}
};
using namespace CGAL::Three; using namespace CGAL::Three;
class Polyhedron_demo_polyhedron_stitching_plugin : class Polyhedron_demo_polyhedron_stitching_plugin :
public QObject, public QObject,
@ -90,30 +71,6 @@ public Q_SLOTS:
}; // end Polyhedron_demo_polyhedron_stitching_plugin }; // end Polyhedron_demo_polyhedron_stitching_plugin
template <typename Poly>
struct Polyline_visitor
{
Scene_polylines_item* new_item;
typename boost::property_map<Poly, CGAL::vertex_point_t>::const_type vpm;
Polyline_visitor(const Poly& poly, Scene_polylines_item* new_item)
: new_item(new_item), vpm(get(CGAL::vertex_point,poly))
{}
void start_new_polyline()
{
new_item->polylines.push_back( Scene_polylines_item::Polyline() );
}
void add_node(typename boost::graph_traits<Poly>::vertex_descriptor vd)
{
new_item->polylines.back().push_back(get(vpm,vd));
}
void end_polyline(){}
};
template <typename Item> template <typename Item>
void Polyhedron_demo_polyhedron_stitching_plugin::on_actionDetectBorders_triggered(Scene_interface::Item_id index) void Polyhedron_demo_polyhedron_stitching_plugin::on_actionDetectBorders_triggered(Scene_interface::Item_id index)
@ -127,18 +84,16 @@ void Polyhedron_demo_polyhedron_stitching_plugin::on_actionDetectBorders_trigger
FaceGraph* pMesh = item->polyhedron(); FaceGraph* pMesh = item->polyhedron();
normalize_border(*pMesh); normalize_border(*pMesh);
for(auto ed : edges(*pMesh))
{
if(pMesh->is_border(ed))
{
new_item->polylines.push_back(Scene_polylines_item::Polyline());
new_item->polylines.back().push_back(pMesh->point(pMesh->source(pMesh->halfedge(ed))));
new_item->polylines.back().push_back(pMesh->point(pMesh->target(pMesh->halfedge(ed))));
}
}
typedef boost::filtered_graph<FaceGraph,Is_border<FaceGraph>, Is_border<FaceGraph> > BorderGraph;
Is_border<FaceGraph> ib(*pMesh);
BorderGraph bg(*pMesh,ib,ib);
Polyline_visitor<FaceGraph> polyline_visitor(*pMesh, new_item);
CGAL::split_graph_into_polylines( bg,
polyline_visitor,
CGAL::internal::IsTerminalDefault() );
if (new_item->polylines.empty()) if (new_item->polylines.empty())
{ {
delete new_item; delete new_item;

View File

@ -260,6 +260,7 @@ struct Scene_surface_mesh_item_priv{
double volume, area; double volume, area;
unsigned int number_of_null_length_edges; unsigned int number_of_null_length_edges;
unsigned int number_of_degenerated_faces; unsigned int number_of_degenerated_faces;
bool has_nm_vertices;
int genus; int genus;
bool self_intersect; bool self_intersect;
mutable QSlider* alphaSlider; mutable QSlider* alphaSlider;
@ -1515,6 +1516,7 @@ invalidate_stats()
{ {
number_of_degenerated_faces = (unsigned int)(-1); number_of_degenerated_faces = (unsigned int)(-1);
number_of_null_length_edges = (unsigned int)(-1); number_of_null_length_edges = (unsigned int)(-1);
has_nm_vertices = false;
volume = -std::numeric_limits<double>::infinity(); volume = -std::numeric_limits<double>::infinity();
area = -std::numeric_limits<double>::infinity(); area = -std::numeric_limits<double>::infinity();
self_intersect = false; self_intersect = false;
@ -1568,11 +1570,30 @@ QString Scene_surface_mesh_item::computeStats(int type)
} }
faces_aspect_ratio(d->smesh_, min_altitude, min_ar, max_ar, mean_ar); faces_aspect_ratio(d->smesh_, min_altitude, min_ar, max_ar, mean_ar);
} }
if(type == HAS_NM_VERTICES)
{
d->has_nm_vertices = false;
typedef boost::function_output_iterator<CGAL::internal::Throw_at_output> OutputIterator;
try{
CGAL::Polygon_mesh_processing::non_manifold_vertices(*d->smesh_, OutputIterator());
}
catch( CGAL::internal::Throw_at_output::Throw_at_output_exception& )
{
d->has_nm_vertices = true;
}
}
switch(type) switch(type)
{ {
case NB_VERTICES: case NB_VERTICES:
return QString::number(num_vertices(*d->smesh_)); return QString::number(num_vertices(*d->smesh_));
case HAS_NM_VERTICES:
{
if(d->has_nm_vertices)
return QString("Yes");
return QString("No");
}
case NB_FACETS: case NB_FACETS:
return QString::number(num_faces(*d->smesh_)); return QString::number(num_faces(*d->smesh_));
@ -1721,14 +1742,15 @@ CGAL::Three::Scene_item::Header_data Scene_surface_mesh_item::header() const
CGAL::Three::Scene_item::Header_data data; CGAL::Three::Scene_item::Header_data data;
//categories //categories
data.categories.append(std::pair<QString,int>(QString("Properties"),9)); data.categories.append(std::pair<QString,int>(QString("Properties"),11));
data.categories.append(std::pair<QString,int>(QString("Faces"),10)); data.categories.append(std::pair<QString,int>(QString("Faces"),10));
data.categories.append(std::pair<QString,int>(QString("Edges"),7)); data.categories.append(std::pair<QString,int>(QString("Edges"),6));
data.categories.append(std::pair<QString,int>(QString("Angles"),2)); data.categories.append(std::pair<QString,int>(QString("Angles"),3));
//titles //titles
data.titles.append(QString("#Vertices")); data.titles.append(QString("#Vertices"));
data.titles.append(QString("Has Non-manifold Vertices"));
data.titles.append(QString("#Connected Components")); data.titles.append(QString("#Connected Components"));
data.titles.append(QString("#Border Edges")); data.titles.append(QString("#Border Edges"));
data.titles.append(QString("Pure Triangle")); data.titles.append(QString("Pure Triangle"));

View File

@ -106,6 +106,7 @@ public:
//statistics //statistics
enum STATS { enum STATS {
NB_VERTICES = 0, NB_VERTICES = 0,
HAS_NM_VERTICES,
NB_CONNECTED_COMPOS, NB_CONNECTED_COMPOS,
NB_BORDER_EDGES, NB_BORDER_EDGES,
IS_PURE_TRIANGLE, IS_PURE_TRIANGLE,

View File

@ -157,8 +157,8 @@ protected:
do do
{ {
internal::newell_single_step_3 internal::newell_single_step_3
(internal::Geom_utils<Kernel>::get_local_point(he->vertex()->point()), (this->get_local_point(he->vertex()->point()),
internal::Geom_utils<Kernel>::get_local_point(he->next()->vertex()->point()), this->get_local_point(he->next()->vertex()->point()),
normal); normal);
++nb; ++nb;
he=he->next(); he=he->next();

View File

@ -24,7 +24,6 @@
#include <CGAL/license/Polytope_distance_d.h> #include <CGAL/license/Polytope_distance_d.h>
#ifdef SIMPLIFY #ifdef SIMPLIFY
#define GCD_COMPUTATION 1 #define GCD_COMPUTATION 1
#endif #endif
@ -98,16 +97,16 @@
#include<iostream> #include<iostream>
#define DEBUGENDL(doit,msg,var)\ #define DEBUGENDL(doit,msg,var)\
if(doit!=0) std::cout << msg << " " << var << endl; if(doit!=0) std::cout << msg << " " << var << std::endl;
#define DEBUGPRINT(doit,msg,var)\ #define DEBUGPRINT(doit,msg,var)\
if(doit!=0) std::cout << msg << " " << var; if(doit!=0) std::cout << msg << " " << var;
#define DEBUGMSG(doit,msg)\ #define DEBUGMSG(doit,msg)\
if(doit!=0) std::cout << msg << endl; if(doit!=0) std::cout << msg << std::endl;
#define INFOMSG(doit,msg)\ #define INFOMSG(doit,msg)\
if(doit!=0) std::cerr<<msg<<endl; if(doit!=0) std::cerr<<msg<<std::endl;
#else #else
#define DEBUGENDL(doit,msg,var) #define DEBUGENDL(doit,msg,var)

View File

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

View File

@ -75,6 +75,16 @@ class Handle
return *this; return *this;
} }
void reset()
{
if (PTR)
{
if (--PTR->count==0)
delete PTR;
PTR=0;
}
}
int int
refs() const { return PTR->count; } refs() const { return PTR->count; }

View File

@ -1,6 +1,9 @@
#!/bin/bash #!/bin/bash
# this script requires ghi: https://github.com/stephencelis/ghi # this script requires ghi: https://github.com/stephencelis/ghi
# See the wiki for how to assign a token to connect without password:
# https://github.com/stephencelis/ghi/wiki/FAQ
#
# example calls within a git repo # example calls within a git repo
# bash tag_pr_per_release.sh 4.12 4.12.1 # bash tag_pr_per_release.sh 4.12 4.12.1
# bash tag_pr_per_release.sh 4.12 4.13 # bash tag_pr_per_release.sh 4.12 4.13
@ -26,7 +29,7 @@ for i in ${PR_LIST}; do
done done
read -p "Please confirm operation by typing YES? " -n 4 -r read -p "Please confirm operation by typing YES? " -n 4 -r
echo # (optional) move to a new line echo
if [[ $REPLY =~ ^YES$ ]]; then if [[ $REPLY =~ ^YES$ ]]; then
for i in ${PR_LIST}; do for i in ${PR_LIST}; do

View File

@ -53,6 +53,8 @@
create_cmake_script_with_options() create_cmake_script_with_options()
{ {
qt4='n'
# parse options file # parse options file
if [ -e "$OPTIONS_FILE" ]; then if [ -e "$OPTIONS_FILE" ]; then
@ -97,8 +99,6 @@ create_cmake_script_with_options()
# Created by the script cgal_create_CMakeLists # Created by the script cgal_create_CMakeLists
# This is the CMake script for compiling a set of CGAL applications. # This is the CMake script for compiling a set of CGAL applications.
cmake_minimum_required(VERSION 3.1...3.14)
EOF EOF
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
if [ "$SINGLE_SOURCE" = "n" ]; then if [ "$SINGLE_SOURCE" = "n" ]; then
@ -110,15 +110,22 @@ EOF
#vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
cat << 'EOF' cat << 'EOF'
cmake_minimum_required(VERSION 2.8.11)
# CGAL and its components # CGAL and its components
EOF EOF
if [ -n "$ENABLE_CTEST" ]; then
echo "enable_testing()"
fi
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# echo "CGAL_COMPONENTS: $CGAL_COMPONENTS" # echo "CGAL_COMPONENTS: $CGAL_COMPONENTS"
if [ ! -z "$CGAL_COMPONENTS" ]; then if [ ! -z "$CGAL_COMPONENTS" ]; then
# ensure capitalization # ensure capitalization
# CGAL: Core, PDB, ImageIO # CGAL: Core, Qt4, PDB, ImageIO
CGAL_COMPONENTS=${CGAL_COMPONENTS//[c|C][o|O][r|R][e|E]/Core} CGAL_COMPONENTS=${CGAL_COMPONENTS//[c|C][o|O][r|R][e|E]/Core}
CGAL_COMPONENTS=${CGAL_COMPONENTS//[q|Q][t|T]4/Qt4}
CGAL_COMPONENTS=${CGAL_COMPONENTS//[i|I][m|M][a|A][g|G][e|E][i|I][o|O]/ImageIO} CGAL_COMPONENTS=${CGAL_COMPONENTS//[i|I][m|M][a|A][g|G][e|E][i|I][o|O]/ImageIO}
# external libs # external libs
@ -154,35 +161,120 @@ EOF
IFS=':' IFS=':'
for cgal_component in $CGAL_COMPONENTS; do for cgal_component in $CGAL_COMPONENTS; do
COMPONENT=`echo $cgal_component | tr '[:upper:]' '[:lower:]'` COMPONENT=`echo $cgal_component | tr '[:upper:]' '[:lower:]'`
# for qtmoc
if [ "$COMPONENT" = "qt4" ]; then
qt4='y'
fi
done done
IFS=$OLDIFS IFS=$OLDIFS
fi fi
if [ -n "${CGAL_COMPONENTS}" ]; then echo "find_package( CGAL QUIET COMPONENTS ${CGAL_COMPONENTS//:/ } )"
echo "find_package( CGAL REQUIRED OPTIONAL_COMPONENTS ${CGAL_COMPONENTS//:/ } )"
else
echo "find_package( CGAL REQUIRED )"
fi
#vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
cat << 'EOF'
if [ ! -z "$BOOST_COMPONENTS" ]; then if ( NOT CGAL_FOUND )
cat << 'EOF'
message(STATUS "This project requires the CGAL library, and will not be compiled.")
return()
endif()
EOF
#---------------------------------------------------------------------------
#vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
cat << 'EOF'
# Boost and its components # Boost and its components
EOF EOF
echo "find_package( Boost REQUIRED OPTIONAL_COMPONENTS ${BOOST_COMPONENTS//:/ } )"
fi # additional Boost components
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
if [ -d include ] ; then if [ ! -z "$BOOST_COMPONENTS" ]; then
cat << 'EOF'
echo "find_package( Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS//:/ } )"
else
echo "find_package( Boost REQUIRED )"
fi # additional Boost components
#vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
cat << 'EOF'
if ( NOT Boost_FOUND )
message(STATUS "This project requires the Boost library, and will not be compiled.")
return()
endif()
EOF
#---------------------------------------------------------------------------
#vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
cat << 'EOF'
# include for local directory # include for local directory
EOF EOF
#---------------------------------------------------------------------------
if [ -d include ] ; then
echo 'include_directories( BEFORE include )' echo 'include_directories( BEFORE include )'
fi fi
#vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
cat << 'EOF'
# include for local package
EOF
#---------------------------------------------------------------------------
# includes for local package
if [ -d ../include ] ; then
echo 'include_directories( BEFORE ../include )'
fi
if [ ! -z "$PACKAGES" ]; then
#vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
cat << 'EOF'
# include of additional packages
EOF
#-------------------------------------------------------------------------
fi
# Qt4
if [ "$qt4" = "y" ]; then
#vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
cat << 'EOF'
# Qt4
set( QT_USE_QTXML true )
set( QT_USE_QTMAIN true )
set( QT_USE_QTSCRIPT true )
set( QT_USE_QTOPENGL true )
find_package(Qt4)
if ( NOT QT_FOUND )
message(STATUS "This project requires the Qt4 library, and will not be compiled.")
return()
endif()
EOF
#-------------------------------------------------------------------------
fi #qt4
if [ ! -z "$BOOST_COMPONENTS" ]; then if [ ! -z "$BOOST_COMPONENTS" ]; then
#vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
cat << 'EOF' cat << 'EOF'
@ -196,7 +288,7 @@ EOF
for boost_component in $BOOST_COMPONENTS; do for boost_component in $BOOST_COMPONENTS; do
BOOST_COMPONENT=`echo $boost_component | tr '[:lower:]' '[:upper:]'` BOOST_COMPONENT=`echo $boost_component | tr '[:lower:]' '[:upper:]'`
echo "add_definitions( \"-DCGAL_USE_BOOST_${BOOST_COMPONENT}\" )" echo "add_definitions( \"-DCGAL_USE_BOOST_${BOOST_COMPONENT}\" )"
echo "list(APPEND CGAL_3RD_PARTY_LIBRARIES Boost::${boost_component} )" echo "list(APPEND CGAL_3RD_PARTY_LIBRARIES \${Boost_${BOOST_COMPONENT}_LIBRARY} )"
done done
IFS=$OLDIFS IFS=$OLDIFS
@ -214,12 +306,33 @@ EOF
#vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv #vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
cat << 'EOF' cat << 'EOF'
# Creating entries for all C++ files with "main" routine # Creating entries for all C++ files with "main" routine
# ########################################################## # ##########################################################
EOF EOF
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# add a new line
echo
# Qt4
if [ "$qt4" = "y" ]; then
#vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
cat << 'EOF'
if ( CGAL_Qt4_FOUND AND QT_FOUND )
include( ${QT_USE_FILE} )
include_directories( ${QT_INCLUDE_DIR} )
endif()
EOF
#-----------------------------------------------------------------------
fi # qt4
for file in `ls *.cc *.cp *.cxx *.cpp *.CPP *.c++ *.C 2> /dev/null | sort` ; do for file in `ls *.cc *.cp *.cxx *.cpp *.CPP *.c++ *.C 2> /dev/null | sort` ; do
# Create an executable for each cpp that contains a function "main()" # Create an executable for each cpp that contains a function "main()"
BASE=`basename $file .cc` BASE=`basename $file .cc`
@ -231,8 +344,32 @@ EOF
BASE=`basename $BASE .C` BASE=`basename $BASE .C`
egrep '\bmain[ \t]*\(' $file >/dev/null 2>&1 egrep '\bmain[ \t]*\(' $file >/dev/null 2>&1
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
echo "create_single_source_cgal_program( \"$file\" )" if [ "$qt4" = "y" ]; then
echo "create_single_source_cgal_program_qt4( \"$file\" )"
else
echo "create_single_source_cgal_program( \"$file\" )"
fi
if [ -n "$ENABLE_CTEST" ]; then
if [ -f "$BASE.cin" ] ; then
CIN=" < $BASE.cin"
else
CIN=
fi
cat <<EOF
add_test( "$BASE" \${CMAKE_CTEST_COMMAND}
--build-and-test "\${CMAKE_CURRENT_SOURCE_DIR}"
"\${CMAKE_CURRENT_BINARY_DIR}"
--build-generator "\${CMAKE_GENERATOR}"
--build-makeprogram "\${CMAKE_MAKE_PROGRAM}"
--build-target $BASE
--build-no-clean
--build-run-dir "\${CMAKE_CURRENT_SOURCE_DIR}"
--test-command sh -c "\${CMAKE_CURRENT_BINARY_DIR}/$BASE$CIN" )
EOF
fi
fi fi
#add a new line
echo
done done
else #====================================================================== else #======================================================================
@ -256,6 +393,73 @@ EOF
all="$all $file" all="$all $file"
done done
# Qt4
if [ "$qt4" = "y" ]; then
#vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
cat << 'EOF'
if ( CGAL_Qt4_FOUND AND QT_FOUND )
include( ${QT_USE_FILE} )
include_directories( ${QT_INCLUDE_DIR} )
EOF
#-----------------------------------------------------------------------
echo " # UI files (Qt Designer files)"
for file in `ls *.ui 2> /dev/null | sort`; do
echo " qt4_wrap_ui( DT_UI_FILES $file )"
done
echo
echo " # qrc files (resources files, that contain icons, at least)"
for file in `ls *.qrc 2> /dev/null | sort`; do
echo " qt4_add_resources ( DT_RESOURCE_FILES ./$file )"
done
echo
MOC_FILES=""
echo " # use the Qt MOC preprocessor on classes that derives from QObject"
for file in `ls include/*.h 2> /dev/null | sort`; do
BASE=`basename $file .h`
egrep 'Q_OBJECT' $file >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo " qt4_generate_moc( include/${BASE}.h ${BASE}.moc )"
MOC_FILES="${BASE}.moc $MOC_FILES"
fi
done
for file in `ls *.h 2> /dev/null | sort`; do
BASE=`basename $file .h`
egrep 'Q_OBJECT' $file >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo " qt4_generate_moc( ${BASE}.h ${BASE}.moc )"
MOC_FILES="${BASE}.moc $MOC_FILES"
fi
done
for file in `ls *.cc *.cp *.cxx *.cpp *.CPP *.c++ *.C 2> /dev/null | sort` ; do
BASE=`basename $file .cc`
BASE=`basename $BASE .cp`
BASE=`basename $BASE .cxx`
BASE=`basename $BASE .cpp`
BASE=`basename $BASE .CPP`
BASE=`basename $BASE .c++`
BASE=`basename $BASE .C`
egrep 'Q_OBJECT' $file >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo " qt4_generate_moc( ${BASE}.cpp ${BASE}.moc )"
MOC_FILES="${BASE}.moc $MOC_FILES"
fi
done
#vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
cat << 'EOF'
endif()
EOF
#-----------------------------------------------------------------------
all="${all} ${MOC_FILES} \${DT_UI_FILES} \${DT_RESOURCE_FILES}"
fi # qt4
# no 'cat' here, as variable substitution required # no 'cat' here, as variable substitution required
echo echo
echo "add_executable( ${target_name} ${all} )" echo "add_executable( ${target_name} ${all} )"
@ -264,11 +468,20 @@ EOF
echo echo
echo "# Link the executable to CGAL and third-party libraries" echo "# Link the executable to CGAL and third-party libraries"
LIBS="" LIBS=""
LIBS=$LIBS" \${CGAL_LIBRARIES} \${CGAL_3RD_PARTY_LIBRARIES}" for comp in ${CGAL_COMPONENTS}; do
echo "target_link_libraries(${target_name} $LIBS )" LIBS=$LIBS" CGAL::CGAL_${comp}"
done
echo "target_link_libraries(${target_name} PRIVATE CGAL::CGAL${LIBS} )"
fi # single source or all files #=========================================== fi # single source or all files #===========================================
#vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
cat << 'EOF'
EOF
#---------------------------------------------------------------------------
echo
} }
usage() usage()
@ -276,9 +489,9 @@ usage()
echo "Usage: `basename $0` [-s source] [-c cgal-component1:cgal-component2:...] [-b boost-component1:boost-component2:...] [-p] [-o options_file='`pwd`/cgal_cmake_options:$HOME/.cgal_cmake_options_rc'] [-v] [-h]" >&2 echo "Usage: `basename $0` [-s source] [-c cgal-component1:cgal-component2:...] [-b boost-component1:boost-component2:...] [-p] [-o options_file='`pwd`/cgal_cmake_options:$HOME/.cgal_cmake_options_rc'] [-v] [-h]" >&2
echo >&2 echo >&2
echo " -s source If this parameter is given the script will create one single executable for 'source' with all source files; otherwise it creates one executable for each main'ed source." >&2 echo " -s source If this parameter is given the script will create one single executable for 'source' with all source files; otherwise it creates one executable for each main'ed source." >&2
echo " cgal_componentX - must be a valid cgal component, examples are 'Core','ImageIO'." >&2 echo " cgal_componentX - must be a valid cgal component, examples are 'Core','ImageIO','Qt4' ('benchmark', 'symbolic')." >&2
echo " boost_componentX - must be a valid boost component, like 'filesystem', 'program_options'." >&2 echo " boost_componentX - must be a valid boost component, like 'filesystem', 'program_options'." >&2
echo " -o options_file - file with CGAL_COMPONENT, and BOOST_COMPONENT directives" >&2 echo " -o options_file - file with PACKAGE, DIRECTORY, CGAL_COMPONENT, and BOOST_COMPONENT directives" >&2
echo " -v the version" >&2 echo " -v the version" >&2
echo " -h this info screen" >&2 echo " -h this info screen" >&2
echo >&2 echo >&2
@ -363,6 +576,8 @@ while getopts s:c:b:o:phvt OPT; do
exit 1 exit 1
fi fi
;; ;;
t) ENABLE_CTEST='y'
;;
h) usage h) usage
exit 0 exit 0
;; ;;

View File

@ -157,7 +157,8 @@ public:
public: public:
No_lvalue_iterator() : point(NULL), idx(0) { } No_lvalue_iterator() : point(NULL), idx(0) { }
No_lvalue_iterator(const Point& point, std::size_t idx = 0) : point(new Point(point)), idx(idx) { } 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) { }
private: private:
@ -279,9 +280,6 @@ class Distance_adapter : public Base_distance {
PointPropertyMap ppmap; PointPropertyMap ppmap;
typedef typename Base_distance::FT FT; typedef typename Base_distance::FT FT;
CGAL_static_assertion( ( boost::is_same< boost::lvalue_property_map_tag,
typename boost::property_traits<PointPropertyMap>::category
>::value ) );
public: public:
Distance_adapter( const PointPropertyMap& ppmap_=PointPropertyMap(), Distance_adapter( const PointPropertyMap& ppmap_=PointPropertyMap(),

View File

@ -1758,6 +1758,8 @@ public:
/// With `check_all_incident_halfedges == false` the function returns `true`, if the incident /// With `check_all_incident_halfedges == false` the function returns `true`, if the incident
/// halfedge associated to vertex `v` is a border halfedge, or if the vertex is isolated. /// halfedge associated to vertex `v` is a border halfedge, or if the vertex is isolated.
/// \cgalAdvancedEnd /// \cgalAdvancedEnd
/// \attention If the data contained in the `Surface_mesh` is not a 2-manifold, then
/// this operation is not guaranteed to return the right result.
bool is_border(Vertex_index v, bool check_all_incident_halfedges = true) const bool is_border(Vertex_index v, bool check_all_incident_halfedges = true) const
{ {
Halfedge_index h(halfedge(v)); Halfedge_index h(halfedge(v));

View File

@ -165,8 +165,8 @@ protected:
do do
{ {
internal::newell_single_step_3 internal::newell_single_step_3
(internal::Geom_utils<Kernel>::get_local_point(sm.point(sm.source(he))), (this->get_local_point(sm.point(sm.source(he))),
internal::Geom_utils<Kernel>::get_local_point(sm.point(sm.target(he))), normal); this->get_local_point(sm.point(sm.target(he))), normal);
++nb; ++nb;
he=sm.next(he); he=sm.next(he);
} }

View File

@ -42,6 +42,9 @@
#if defined(CGAL_EIGEN3_ENABLED) #if defined(CGAL_EIGEN3_ENABLED)
#include <CGAL/Eigen_solver_traits.h> #include <CGAL/Eigen_solver_traits.h>
#ifdef CGAL_SMP_USE_SPARSESUITE_SOLVERS
#include <Eigen/UmfPackSupport>
#endif
#endif #endif
#include <CGAL/assertions.h> #include <CGAL/assertions.h>
@ -156,7 +159,14 @@ namespace Surface_mesh_parameterization {
/// and `CGAL_EIGEN3_ENABLED` is defined, then an overload of `Eigen_solver_traits` /// and `CGAL_EIGEN3_ENABLED` is defined, then an overload of `Eigen_solver_traits`
/// is provided as default parameter: /// is provided as default parameter:
/// \code /// \code
/// CGAL::Eigen_solver_traits<Eigen::BICGSTAB< Eigen::SparseMatrix<double> > > /// CGAL::Eigen_solver_traits<
/// Eigen::SparseLU<Eigen_sparse_matrix<double>::EigenType> >
/// \endcode
/// Moreover, if SparseSuite solvers are available, which is greatly preferable for speed,
/// then the default parameter is:
/// \code
/// CGAL::Eigen_solver_traits<
/// Eigen::UmfPackLU<Eigen_sparse_matrix<double>::EigenType> >
/// \endcode /// \endcode
/// ///
/// \sa `CGAL::Surface_mesh_parameterization::Fixed_border_parameterizer_3<TriangleMesh, BorderParameterizer, SolverTraits>` /// \sa `CGAL::Surface_mesh_parameterization::Fixed_border_parameterizer_3<TriangleMesh, BorderParameterizer, SolverTraits>`
@ -175,7 +185,13 @@ public:
typedef typename Default::Get< typedef typename Default::Get<
SolverTraits_, SolverTraits_,
#if defined(CGAL_EIGEN3_ENABLED) #if defined(CGAL_EIGEN3_ENABLED)
Eigen_solver_traits< > // defaults to Eigen::BICGSTAB with Eigen_sparse_matrix #ifdef CGAL_SMP_USE_SPARSESUITE_SOLVERS
CGAL::Eigen_solver_traits<
Eigen::UmfPackLU<Eigen_sparse_matrix<double>::EigenType> >
#else
CGAL::Eigen_solver_traits<
Eigen::SparseLU<Eigen_sparse_matrix<double>::EigenType> >
#endif
#else #else
#pragma message("Error: You must either provide 'SolverTraits_' or link CGAL with the Eigen library") #pragma message("Error: You must either provide 'SolverTraits_' or link CGAL with the Eigen library")
SolverTraits_ // no parameter provided, and Eigen is not enabled: so don't compile! SolverTraits_ // no parameter provided, and Eigen is not enabled: so don't compile!
@ -289,19 +305,26 @@ private:
std::ostringstream out_ss; std::ostringstream out_ss;
out_ss << filename << iter << ".off" << std::ends; out_ss << filename << iter << ".off" << std::ends;
std::ofstream out(out_ss.str().c_str()); std::ofstream out(out_ss.str().c_str());
output_uvmap_to_off(mesh, vertices, faces, uvmap, vimap, out); IO::output_uvmap_to_off(mesh, vertices, faces, uvmap, vimap, out);
} }
// Copy the data from two vectors to the UVmap. // Copy the data from two vectors to the UVmap.
template <typename VertexUVMap, template <typename VertexUVMap,
typename VertexIndexMap> typename VertexIndexMap,
typename VertexParameterizedMap>
void assign_solution(const Vector& Xu, void assign_solution(const Vector& Xu,
const Vector& Xv, const Vector& Xv,
const Vertex_set& vertices, const Vertex_set& vertices,
VertexUVMap uvmap, VertexUVMap uvmap,
const VertexIndexMap vimap) const VertexIndexMap vimap,
const VertexParameterizedMap vpmap)
{ {
for(vertex_descriptor vd : vertices) { for(vertex_descriptor vd : vertices) {
// The solver might not have managed to exactly constrain the vertex that was marked
// as constrained; simply don't update its position.
if(get(vpmap, vd))
continue;
int index = get(vimap, vd); int index = get(vimap, vd);
NT u = Xu(index); NT u = Xu(index);
NT v = Xv(index); NT v = Xv(index);
@ -1115,13 +1138,13 @@ private:
for(vertex_descriptor vd : vertices) { for(vertex_descriptor vd : vertices) {
if(get(vpmap, vd)) { if(get(vpmap, vd)) {
int index = get(vimap, vd); int index = get(vimap, vd);
CGAL_postcondition(std::abs(Xu[index] - Bu[index] ) < 1e-10); CGAL_warning(std::abs(Xu[index] - Bu[index] ) < 1e-7);
CGAL_postcondition(std::abs(Xv[index] - Bv[index] ) < 1e-10); CGAL_warning(std::abs(Xv[index] - Bv[index] ) < 1e-7);
} }
} }
) )
assign_solution(Xu, Xv, vertices, uvmap, vimap); assign_solution(Xu, Xv, vertices, uvmap, vimap, vpmap);
return status; return status;
} }
@ -1339,49 +1362,62 @@ public:
#endif #endif
// main loop // main loop
for(unsigned int ite=1; ite<=m_iterations; ++ite) unsigned int ite = 1;
for(;;)
{ {
compute_optimal_Lt_matrices(mesh, faces, ctmap, lp, lpmap, uvmap, ltmap); compute_optimal_Lt_matrices(mesh, faces, ctmap, lp, lpmap, uvmap, ltmap);
status = update_solution(mesh, vertices, ctmap, lp, lpmap, ltmap, status = update_solution(mesh, vertices, ctmap, lp, lpmap, ltmap,
uvmap, vimap, vpmap, A); uvmap, vimap, vpmap, A);
// Output the current situation // Output the current parameterization
#ifdef CGAL_SMP_ARAP_DEBUG #ifdef CGAL_SMP_ARAP_DEBUG
output_uvmap("ARAP_iteration_", ite, mesh, vertices, faces, uvmap vimap); output_uvmap("ARAP_iteration_", ite, mesh, vertices, faces, uvmap, vimap);
#endif #endif
energy_last = energy_this;
energy_this = compute_current_energy(mesh, faces, ctmap, lp, lpmap,
ltmap, uvmap);
#ifdef CGAL_PARAMETERIZATION_ARAP_VERBOSE
std::cout << "Energy at iteration " << ite << " : " << energy_this << std::endl;
#endif
CGAL_warning(energy_this >= 0);
if(status != OK) if(status != OK)
return status; return status;
// energy based termination // energy based termination
if(m_tolerance > 0.0 && ite <= m_iterations) // if tolerance <= 0, don't compute energy if(m_tolerance > 0. && ite <= m_iterations) { // if tolerance <= 0, don't compute energy
{ // also no need compute energy if this iteration is the last iteration energy_last = energy_this;
energy_this = compute_current_energy(mesh, faces, ctmap, lp, lpmap, ltmap, uvmap);
#ifdef CGAL_PARAMETERIZATION_ARAP_VERBOSE
std::cout << "Energy at iteration " << ite << " : " << energy_this << std::endl;
#endif
if(energy_this < 0) {
// numerical issues can make it so you may get an energy of -1e-17,
// but it shouldn't be too wrong
CGAL_assertion(energy_this >= - std::numeric_limits<NT>::epsilon());
break;
}
double energy_diff = std::abs((energy_last - energy_this) / energy_this); double energy_diff = std::abs((energy_last - energy_this) / energy_this);
if(energy_diff < m_tolerance) { if(energy_diff < m_tolerance) {
#ifdef CGAL_PARAMETERIZATION_ARAP_VERBOSE
std::cout << "Minimization process ended after: "
<< ite + 1 << " iterations. "
<< "Energy diff: " << energy_diff << std::endl;
#endif
break; break;
} }
} }
if(ite >= m_iterations)
break;
else
++ite;
} }
#ifdef CGAL_PARAMETERIZATION_ARAP_VERBOSE
std::cout << "Minimization process ended after: " << ite << " iterations. " << std::endl;
#endif
#ifdef CGAL_SMP_ARAP_DEBUG #ifdef CGAL_SMP_ARAP_DEBUG
output_uvmap("ARAP_final_pre_processing.off", mesh, vertices, faces, uvmap, vimap); output_uvmap("ARAP_final_pre_processing.off", mesh, vertices, faces, uvmap, vimap);
#endif #endif
if(!is_one_to_one_mapping(mesh, faces, uvmap)) { if(!is_one_to_one_mapping(mesh, faces, uvmap)) {
// Use post processing to handle flipped elements // Use post processing to handle flipped elements
std::cerr << "Parameterization is not valid; calling post processor" << std::endl; #ifdef CGAL_PARAMETERIZATION_ARAP_VERBOSE
std::cout << "Parameterization is not valid; calling post processor" << std::endl;
#endif
status = post_process(mesh, vertices, faces, bhd, uvmap, vimap); status = post_process(mesh, vertices, faces, bhd, uvmap, vimap);
} }

View File

@ -291,7 +291,7 @@ private:
{ {
// Build the constrained triangulation // Build the constrained triangulation
// Since the border is closed and we are interest in triangles that are outside // Since the border is closed and we are interested in triangles that are outside
// of the border, we actually only need to insert points on the border // of the border, we actually only need to insert points on the border
for(halfedge_descriptor hd : halfedges_around_face(bhd, mesh)) { for(halfedge_descriptor hd : halfedges_around_face(bhd, mesh)) {
vertex_descriptor s = source(hd, mesh); vertex_descriptor s = source(hd, mesh);

View File

@ -126,6 +126,7 @@ private:
typename GeomTraits::Construct_normal_3 normal_functor; typename GeomTraits::Construct_normal_3 normal_functor;
typename GeomTraits::Construct_translated_point_3 translated_point_functor; typename GeomTraits::Construct_translated_point_3 translated_point_functor;
typename GeomTraits::Construct_centroid_3 centroid_functor; typename GeomTraits::Construct_centroid_3 centroid_functor;
typename GeomTraits::Collinear_3 collinear_functor;
Tree tree; Tree tree;
@ -153,11 +154,11 @@ public:
normal_functor(traits.construct_normal_3_object()), normal_functor(traits.construct_normal_3_object()),
translated_point_functor(traits.construct_translated_point_3_object()), translated_point_functor(traits.construct_translated_point_3_object()),
centroid_functor(traits.construct_centroid_3_object()), centroid_functor(traits.construct_centroid_3_object()),
collinear_functor(traits.collinear_3_object()),
tree(create_traits(mesh, vertex_point_map)), tree(create_traits(mesh, vertex_point_map)),
use_diagonal(use_diagonal) use_diagonal(use_diagonal)
{ {
typedef typename boost::property_traits<VertexPointPmap>::reference Point_ref; typedef typename boost::property_traits<VertexPointPmap>::reference Point_ref;
typename GeomTraits::Collinear_3 collinear = traits.collinear_3_object();
face_iterator it, end; face_iterator it, end;
for(it = faces(mesh).begin(), end = faces(mesh).end(); it!=end; it++) for(it = faces(mesh).begin(), end = faces(mesh).end(); it!=end; it++)
{ {
@ -167,7 +168,7 @@ public:
Point_ref b(get(vertex_point_map,target(h, mesh))); Point_ref b(get(vertex_point_map,target(h, mesh)));
h = next(h, mesh); h = next(h, mesh);
Point_ref c(get(vertex_point_map, target(h, mesh))); Point_ref c(get(vertex_point_map, target(h, mesh)));
bool test = collinear(a,b,c); bool test = collinear_functor(a,b,c);
if(!test) if(!test)
tree.insert(Primitive(it, mesh, vertex_point_map)); tree.insert(Primitive(it, mesh, vertex_point_map));
} }
@ -388,10 +389,11 @@ private:
const Point p2 = get(vertex_point_map,target(next(halfedge(facet,mesh),mesh),mesh)); const Point p2 = get(vertex_point_map,target(next(halfedge(facet,mesh),mesh),mesh));
const Point p3 = get(vertex_point_map,target(prev(halfedge(facet,mesh),mesh),mesh)); const Point p3 = get(vertex_point_map,target(prev(halfedge(facet,mesh),mesh),mesh));
const Point center = centroid_functor(p1, p2, p3); const Point center = centroid_functor(p1, p2, p3);
if (collinear_functor(p1, p2, p3)) return boost::none;
Vector normal = normal_functor(p2, p1, p3); Vector normal = normal_functor(p2, p1, p3);
normal=scale_functor(normal, normal=scale_functor(normal,
FT(1.0/std::sqrt(to_double(normal.squared_length())))); FT(1.0/std::sqrt(to_double(normal.squared_length()))));
if (normal!=normal) return boost::none;
CGAL::internal::SkipPrimitiveFunctor<face_handle> CGAL::internal::SkipPrimitiveFunctor<face_handle>
skip(facet); skip(facet);
CGAL::internal::FirstIntersectionVisitor<face_handle> CGAL::internal::FirstIntersectionVisitor<face_handle>

View File

@ -152,9 +152,9 @@ typename Traits::Barycentric_coordinates random_coordinates(CGAL::Random& rand)
{ {
typedef typename Traits::FT FT; typedef typename Traits::FT FT;
typename Traits::Construct_barycentric_coordinates construct_barycentric_coordinates; typename Traits::Construct_barycentric_coordinates construct_barycentric_coordinates;
FT u = rand.uniform_real(FT(0.0), FT(1.0)); FT u = rand.uniform_real(FT(0), FT(1));
FT v = rand.uniform_real(FT(0.0), FT(1.0) - u); FT v = rand.uniform_real(FT(0), FT(1) - u);
return construct_barycentric_coordinates(u, v, FT(1.0) - u - v); return construct_barycentric_coordinates(u, v, FT(1) - u - v);
} }
template <class Kernel> template <class Kernel>

View File

@ -58,7 +58,9 @@ public:
{ {
} }
Construct_barycentric_coordinates_in_triangle_2(const Construct_barycentric_coordinates& cbc, const Construct_vector_2& cv2, const Compute_scalar_product_2& csp2) Construct_barycentric_coordinates_in_triangle_2(const Construct_barycentric_coordinates& cbc,
const Construct_vector_2& cv2,
const Compute_scalar_product_2& csp2)
: m_construct_barycentric_coordinates(cbc) : m_construct_barycentric_coordinates(cbc)
, m_construct_vector_2(cv2) , m_construct_vector_2(cv2)
, m_compute_scalar_product_2(csp2) , m_compute_scalar_product_2(csp2)
@ -81,7 +83,7 @@ public:
FT v = (d11 * d20 - d01 * d21) / denom; FT v = (d11 * d20 - d01 * d21) / denom;
FT w = (d00 * d21 - d01 * d20) / denom; FT w = (d00 * d21 - d01 * d20) / denom;
return m_construct_barycentric_coordinates(FT(1.0) - v - w, v, w); return m_construct_barycentric_coordinates(FT(1) - v - w, v, w);
} }
}; };
@ -109,7 +111,9 @@ public:
{ {
} }
Construct_barycentric_coordinates_in_triangle_3(const Construct_barycentric_coordinates& cbc, const Construct_vector_3& cv3, const Compute_scalar_product_3& csp3) Construct_barycentric_coordinates_in_triangle_3(const Construct_barycentric_coordinates& cbc,
const Construct_vector_3& cv3,
const Compute_scalar_product_3& csp3)
: m_construct_barycentric_coordinates(cbc) : m_construct_barycentric_coordinates(cbc)
, m_construct_vector_3(cv3) , m_construct_vector_3(cv3)
, m_compute_scalar_product_3(csp3) , m_compute_scalar_product_3(csp3)
@ -132,7 +136,7 @@ public:
FT v = (d11 * d20 - d01 * d21) / denom; FT v = (d11 * d20 - d01 * d21) / denom;
FT w = (d00 * d21 - d01 * d20) / denom; FT w = (d00 * d21 - d01 * d20) / denom;
return m_construct_barycentric_coordinates(FT(1.0) - v - w, v, w); return m_construct_barycentric_coordinates(FT(1) - v - w, v, w);
} }
}; };
@ -194,7 +198,8 @@ public:
bool nonZero[3]; bool nonZero[3];
std::size_t numNonZero = 0; std::size_t numNonZero = 0;
if (cbcw(baryCoords, 0) + cbcw(baryCoords, 1) + cbcw(baryCoords, 2) > 1.00001 || cbcw(baryCoords, 0) + cbcw(baryCoords, 1) + cbcw(baryCoords, 2) < 0.99999) if (cbcw(baryCoords, 0) + cbcw(baryCoords, 1) + cbcw(baryCoords, 2) > 1.00001 ||
cbcw(baryCoords, 0) + cbcw(baryCoords, 1) + cbcw(baryCoords, 2) < 0.99999)
{ {
return std::make_pair(BARYCENTRIC_COORDINATES_ON_UNBOUNDED_SIDE, 0); return std::make_pair(BARYCENTRIC_COORDINATES_ON_UNBOUNDED_SIDE, 0);
} }

View File

@ -18,11 +18,10 @@
// //
// Author(s) : Stephen Kiazyk // Author(s) : Stephen Kiazyk
#include <cstddef> #ifndef CGAL_SURFACE_MESH_SHORTEST_PATH_INTERNAL_FUNCTION_OBJECTS_H
#define CGAL_SURFACE_MESH_SHORTEST_PATH_INTERNAL_FUNCTION_OBJECTS_H
#include <boost/graph/graph_traits.hpp> #include <CGAL/license/Surface_mesh_shortest_path.h>
#include <CGAL/result_of.h>
#include <CGAL/assertions.h>
#include <CGAL/Surface_mesh_shortest_path/internal/misc_functions.h> #include <CGAL/Surface_mesh_shortest_path/internal/misc_functions.h>
@ -32,13 +31,15 @@
#endif #endif
#endif #endif
#include <CGAL/assertions.h>
#include <CGAL/boost/graph/helpers.h>
#include <CGAL/number_utils.h>
#include <CGAL/result_of.h>
#include <CGAL/Cartesian_converter.h> #include <CGAL/Cartesian_converter.h>
#ifndef CGAL_SURFACE_MESH_SHORTEST_PATH_INTERNAL_FUNCTION_OBJECTS_H #include <cmath>
#define CGAL_SURFACE_MESH_SHORTEST_PATH_INTERNAL_FUNCTION_OBJECTS_H #include <cstddef>
#include <limits>
#include <CGAL/license/Surface_mesh_shortest_path.h>
namespace CGAL { namespace CGAL {
@ -246,8 +247,8 @@ public:
Point_3 projectedLocation3d(m_construct_projected_point_3(baseSegment, m_construct_vertex_3(t3, 2))); Point_3 projectedLocation3d(m_construct_projected_point_3(baseSegment, m_construct_vertex_3(t3, 2)));
FT scalePoint = m_parametric_distance_along_segment_3(m_construct_vertex_3(t3, 0), m_construct_vertex_3(t3, 1), projectedLocation3d); FT scalePoint = m_parametric_distance_along_segment_3(m_construct_vertex_3(t3, 0), m_construct_vertex_3(t3, 1), projectedLocation3d);
FT triangleHeight = CGAL::internal::select_sqrt(m_compute_squared_distance_3(projectedLocation3d, t3[2])); FT triangleHeight = CGAL::approximate_sqrt(m_compute_squared_distance_3(projectedLocation3d, t3[2]));
FT v01Len = CGAL::internal::select_sqrt(m_compute_squared_distance_3(t3[1], t3[0])); FT v01Len = CGAL::approximate_sqrt(m_compute_squared_distance_3(t3[1], t3[0]));
Point_2 A(m_construct_point_2(0.0, 0.0)); Point_2 A(m_construct_point_2(0.0, 0.0));
Point_2 B(m_construct_point_2(v01Len, 0.0)); Point_2 B(m_construct_point_2(v01Len, 0.0));
@ -367,12 +368,12 @@ public:
{ {
Point_3 projectedLocation3d(m_construct_projected_point_3(m_construct_line_3(m_construct_vertex_3(t3, edgeIndex), m_construct_vertex_3(t3, edgeIndex + 1)), m_construct_vertex_3(t3, edgeIndex + 2))); Point_3 projectedLocation3d(m_construct_projected_point_3(m_construct_line_3(m_construct_vertex_3(t3, edgeIndex), m_construct_vertex_3(t3, edgeIndex + 1)), m_construct_vertex_3(t3, edgeIndex + 2)));
FT scalePoint = m_parametric_distance_along_segment_3(m_construct_segment_3(m_construct_vertex_3(t3, edgeIndex), m_construct_vertex_3(t3, edgeIndex + 1)), projectedLocation3d); FT scalePoint = m_parametric_distance_along_segment_3(m_construct_segment_3(m_construct_vertex_3(t3, edgeIndex), m_construct_vertex_3(t3, edgeIndex + 1)), projectedLocation3d);
FT triangleHeight = CGAL::internal::select_sqrt(m_compute_squared_distance_3(projectedLocation3d, m_construct_vertex_3(t3, edgeIndex + 2))); FT triangleHeight = CGAL::approximate_sqrt(m_compute_squared_distance_3(projectedLocation3d, m_construct_vertex_3(t3, edgeIndex + 2)));
Vector_2 edgeVector(m_construct_vector_2(segment)); Vector_2 edgeVector(m_construct_vector_2(segment));
Vector_2 perpendicularEdgeVector(m_construct_perpendicular_vector_2(edgeVector, CGAL::COUNTERCLOCKWISE)); Vector_2 perpendicularEdgeVector(m_construct_perpendicular_vector_2(edgeVector, CGAL::COUNTERCLOCKWISE));
perpendicularEdgeVector = m_construct_scaled_vector_2(perpendicularEdgeVector, FT(1.0) / CGAL::internal::select_sqrt(m_compute_squared_length_2(perpendicularEdgeVector))); perpendicularEdgeVector = m_construct_scaled_vector_2(perpendicularEdgeVector, FT(1) / CGAL::approximate_sqrt(m_compute_squared_length_2(perpendicularEdgeVector)));
Point_2 points[3]; Point_2 points[3];
points[edgeIndex] = m_construct_source_2(segment); points[edgeIndex] = m_construct_source_2(segment);
@ -433,16 +434,19 @@ public:
typedef typename K::Intersect_2 Intersect_2; typedef typename K::Intersect_2 Intersect_2;
typedef typename K::Compare_distance_2 Compare_distance_2; typedef typename K::Compare_distance_2 Compare_distance_2;
typedef typename K::Compute_squared_distance_2 Compute_squared_distance_2;
typedef typename K::Construct_line_2 Construct_line_2; typedef typename K::Construct_line_2 Construct_line_2;
typedef typename K::Construct_source_2 Construct_source_2; typedef typename K::Construct_source_2 Construct_source_2;
typedef typename K::Construct_target_2 Construct_target_2; typedef typename K::Construct_target_2 Construct_target_2;
typedef CGAL::Comparison_result result_type; typedef CGAL::Comparison_result result_type;
private: private:
Compute_parametric_distance_along_segment_2<K> m_parametric_distance_along_segment_2; Compute_parametric_distance_along_segment_2<K> m_parametric_distance_along_segment_2;
Intersect_2 m_intersect_2; Intersect_2 m_intersect_2;
Compare_distance_2 m_compare_distance_2; Compare_distance_2 m_compare_distance_2;
Compute_squared_distance_2 m_compute_squared_distance_2;
Construct_line_2 m_construct_line_2; Construct_line_2 m_construct_line_2;
Construct_source_2 m_construct_source_2; Construct_source_2 m_construct_source_2;
Construct_target_2 m_construct_target_2; Construct_target_2 m_construct_target_2;
@ -455,6 +459,7 @@ public:
Compare_relative_intersection_along_segment_2(const K& kernel) Compare_relative_intersection_along_segment_2(const K& kernel)
: m_intersect_2(kernel.intersect_2_object()) : m_intersect_2(kernel.intersect_2_object())
, m_compare_distance_2(kernel.compare_distance_2_object()) , m_compare_distance_2(kernel.compare_distance_2_object())
, m_compute_squared_distance_2(kernel.compute_squared_distance_2_object())
, m_construct_line_2(kernel.construct_line_2_object()) , m_construct_line_2(kernel.construct_line_2_object())
, m_construct_source_2(kernel.construct_source_2_object()) , m_construct_source_2(kernel.construct_source_2_object())
, m_construct_target_2(kernel.construct_target_2_object()) , m_construct_target_2(kernel.construct_target_2_object())
@ -466,7 +471,6 @@ public:
typedef typename CGAL::cpp11::result_of<Intersect_2(Line_2, Line_2)>::type LineLineIntersectResult; typedef typename CGAL::cpp11::result_of<Intersect_2(Line_2, Line_2)>::type LineLineIntersectResult;
Line_2 s1Line(m_construct_line_2(s1)); Line_2 s1Line(m_construct_line_2(s1));
Line_2 s2Line(m_construct_line_2(s2)); Line_2 s2Line(m_construct_line_2(s2));
LineLineIntersectResult intersectResult1(m_intersect_2(s1Line, l1)); LineLineIntersectResult intersectResult1(m_intersect_2(s1Line, l1));
@ -479,7 +483,7 @@ public:
if (!p1_ptr) return CGAL::SMALLER; if (!p1_ptr) return CGAL::SMALLER;
CGAL_assertion_code(FT t1 = m_parametric_distance_along_segment_2(s1, *p1_ptr);) CGAL_assertion_code(FT t1 = m_parametric_distance_along_segment_2(s1, *p1_ptr);)
CGAL_assertion(t1 >= FT(-0.00001) && t1 <= FT(1.00001)); CGAL_assertion(t1 >= FT(-1)/FT(100000) && t1 <= FT(1)+FT(1)/FT(100000));
LineLineIntersectResult intersectResult2 = m_intersect_2(s2Line, l2); LineLineIntersectResult intersectResult2 = m_intersect_2(s2Line, l2);
CGAL_assertion(bool(intersectResult2)); CGAL_assertion(bool(intersectResult2));
@ -491,9 +495,27 @@ public:
if (!p2_ptr) return CGAL::SMALLER; if (!p2_ptr) return CGAL::SMALLER;
CGAL_assertion_code(FT t2 = m_parametric_distance_along_segment_2(s2, *p2_ptr);) CGAL_assertion_code(FT t2 = m_parametric_distance_along_segment_2(s2, *p2_ptr);)
CGAL_assertion(t2 >= FT(-0.00001) && t2 <= FT(1.00001)); CGAL_assertion(t2 >= FT(-1)/FT(100000) && t2 <= FT(1)+FT(1)/FT(100000));
// #define CGAL_SMSP_DONT_USE_RELAXED_PRUNING
#ifndef CGAL_SMSP_DONT_USE_RELAXED_PRUNING
const FT sqd_1 = m_compute_squared_distance_2(s1.source(), *p1_ptr);
const FT sqd_2 = m_compute_squared_distance_2(s2.source(), *p2_ptr);
// In the case of multiple rays reaching the same target, we want to know their respective position
// so that pruning of branches can be done according to the "one angle one split" idiom.
// However, the orientation predicate is evaluated in the unfolded 2D plane, which is obtained
// via square roots; inconsisnties will exist. We don't want to prune in case it might be wrong,
// so we add a little bit of tolerance on the evaluation of the predicate. If it's almost collinear,
// return 'collinear' (EQUAL).
const FT eps = (FT(100) * std::numeric_limits<FT>::epsilon());
if(CGAL::abs(sqd_1 - sqd_2) < eps)
return CGAL::EQUAL;
return CGAL::compare(sqd_1, sqd_2);
#else
return m_compare_distance_2(s1.source(), *p1_ptr, s2.source(), *p2_ptr); return m_compare_distance_2(s1.source(), *p1_ptr, s2.source(), *p2_ptr);
#endif
} }
}; };
@ -501,13 +523,14 @@ template <class Kernel, class FaceListGraph>
class Is_saddle_vertex class Is_saddle_vertex
{ {
public: public:
typedef typename Kernel::FT FT;
typedef typename Kernel::Point_2 Point_2;
typedef typename Kernel::Point_3 Point_3; typedef typename Kernel::Point_3 Point_3;
typedef typename Kernel::Segment_2 Segment_2;
typedef typename Kernel::Vector_2 Vector_2;
typedef typename Kernel::Vector_3 Vector_3; typedef typename Kernel::Vector_3 Vector_3;
typedef typename Kernel::Triangle_3 Triangle_3; typedef typename Kernel::Triangle_3 Triangle_3;
typedef typename Kernel::Triangle_2 Triangle_2; typedef typename Kernel::Triangle_2 Triangle_2;
typedef typename Kernel::Segment_2 Segment_2;
typedef typename Kernel::Vector_2 Vector_2;
typedef typename Kernel::Point_2 Point_2;
typedef typename boost::graph_traits<FaceListGraph> Graph_traits; typedef typename boost::graph_traits<FaceListGraph> Graph_traits;
typedef typename Graph_traits::vertex_descriptor vertex_descriptor; typedef typename Graph_traits::vertex_descriptor vertex_descriptor;
@ -540,7 +563,9 @@ public:
{ {
} }
Is_saddle_vertex(const Kernel& kernel, const Construct_triangle_3_to_triangle_2_projection& pt3tt2, const Construct_triangle_3_along_segment_2_flattening& ft3as2) Is_saddle_vertex(const Kernel& kernel,
const Construct_triangle_3_to_triangle_2_projection& pt3tt2,
const Construct_triangle_3_along_segment_2_flattening& ft3as2)
: m_orientation_2(kernel.orientation_2_object()) : m_orientation_2(kernel.orientation_2_object())
, m_construct_triangle_3(kernel.construct_triangle_3_object()) , m_construct_triangle_3(kernel.construct_triangle_3_object())
, m_construct_vertex_2(kernel.construct_vertex_2_object()) , m_construct_vertex_2(kernel.construct_vertex_2_object())
@ -557,10 +582,72 @@ public:
return (*this)(v, g, get(boost::vertex_point, g)); return (*this)(v, g, get(boost::vertex_point, g));
} }
FT angle(const Vector_3& u, const Vector_3& v) const
{
typename Kernel::Compute_scalar_product_3 scalar_product;
double product = CGAL::sqrt(to_double(scalar_product(u,u)) * to_double(scalar_product(v,v)));
if(product == 0)
return 0;
// cosine
double dot = to_double(scalar_product(u,v));
double cosine = dot / product;
if(cosine > 1.)
cosine = 1.;
if(cosine < -1.)
cosine = -1.;
return std::acos(cosine) * 180./CGAL_PI;
}
FT angle(const Point_3& p, const Point_3& q, const Point_3& r) const
{
typename Kernel::Construct_vector_3 cv;
Vector_3 u = cv(q, p);
Vector_3 v = cv(q, r);
return angle(u, v);
}
template<class VertexPointMap>
FT vertex_angle(const vertex_descriptor v,
const FaceListGraph& g,
const VertexPointMap& pointMap) const
{
FT angle_sum = 0;
for(halfedge_descriptor h : halfedges_around_target(v, g))
{
if(is_border(h, g))
continue;
angle_sum += angle(get(pointMap, source(h, g)),
get(pointMap, target(h, g)),
get(pointMap, target(next(h, g), g)));
}
angle_sum *= CGAL_PI / FT(180);
return angle_sum;
}
template<class VertexPointMap> template<class VertexPointMap>
result_type operator() (vertex_descriptor v, const FaceListGraph& g, VertexPointMap const& pointMap) const result_type operator() (vertex_descriptor v, const FaceListGraph& g, VertexPointMap const& pointMap) const
{ {
#ifndef CGAL_SMSP_DONT_USE_RELAXED_PRUNING
const FT ang_sum = vertex_angle(v, g, pointMap);
const FT bound = (FT(1) - FT(100) * std::numeric_limits<FT>::epsilon()) * 2 * CGAL_PI;
return (ang_sum >= bound);
#else
halfedge_descriptor startEdge = halfedge(v, g); halfedge_descriptor startEdge = halfedge(v, g);
while (face(startEdge, g) == Graph_traits::null_face())
startEdge=opposite(next(startEdge, g), g);
Point_3 rootPoint(get(pointMap, v)); Point_3 rootPoint(get(pointMap, v));
Point_3 prevPoint(get(pointMap, source(startEdge, g))); Point_3 prevPoint(get(pointMap, source(startEdge, g)));
@ -607,6 +694,7 @@ public:
while (currentEdge != startEdge); while (currentEdge != startEdge);
return false; return false;
#endif
} }
}; };

View File

@ -23,9 +23,8 @@
#include <CGAL/license/Surface_mesh_shortest_path.h> #include <CGAL/license/Surface_mesh_shortest_path.h>
namespace CGAL { namespace CGAL {
namespace Surface_mesh_shortest_paths_3 {
namespace internal { namespace internal {
template<class Traits> template<class Traits>
@ -54,7 +53,9 @@ public:
bool m_cancelled; bool m_cancelled;
public: public:
Cone_expansion_event(Cone_tree_node<Traits>* parent, const FT& distanceEstimate, Expansion_type type) Cone_expansion_event(Cone_tree_node<Traits>* parent,
const FT& distanceEstimate,
Expansion_type type)
: m_parent(parent) : m_parent(parent)
, m_distanceEstimate(distanceEstimate) , m_distanceEstimate(distanceEstimate)
, m_type(type) , m_type(type)
@ -62,7 +63,10 @@ public:
{ {
} }
Cone_expansion_event(Cone_tree_node<Traits>* parent, const FT& distanceEstimate, Expansion_type type, const Segment_2& windowSegment) Cone_expansion_event(Cone_tree_node<Traits>* parent,
const FT& distanceEstimate,
Expansion_type type,
const Segment_2& windowSegment)
: m_parent(parent) : m_parent(parent)
, m_distanceEstimate(distanceEstimate) , m_distanceEstimate(distanceEstimate)
, m_type(type) , m_type(type)
@ -77,14 +81,15 @@ template <class Traits>
struct Cone_expansion_event_min_priority_queue_comparator struct Cone_expansion_event_min_priority_queue_comparator
{ {
public: public:
bool operator () (const Cone_expansion_event<Traits>* lhs, const Cone_expansion_event<Traits>* rhs) const bool operator () (const Cone_expansion_event<Traits>* lhs,
const Cone_expansion_event<Traits>* rhs) const
{ {
return rhs->m_distanceEstimate < lhs->m_distanceEstimate; return rhs->m_distanceEstimate < lhs->m_distanceEstimate;
} }
}; };
} // namespace internal } // namespace internal
} // namespace Surface_mesh_shortest_paths_3
} // namespace CGAL } // namespace CGAL
#endif // CGAL_SURFACE_MESH_SHORTEST_PATH_INTERNAL_CONE_EXPANSION_EVENT_H #endif // CGAL_SURFACE_MESH_SHORTEST_PATH_INTERNAL_CONE_EXPANSION_EVENT_H

View File

@ -23,7 +23,6 @@
#include <CGAL/license/Surface_mesh_shortest_path.h> #include <CGAL/license/Surface_mesh_shortest_path.h>
#include <vector> #include <vector>
#include <boost/graph/graph_traits.hpp> #include <boost/graph/graph_traits.hpp>
@ -32,11 +31,11 @@
#include <CGAL/Surface_mesh_shortest_path/internal/Cone_expansion_event.h> #include <CGAL/Surface_mesh_shortest_path/internal/Cone_expansion_event.h>
#include <CGAL/Surface_mesh_shortest_path/internal/misc_functions.h> #include <CGAL/Surface_mesh_shortest_path/internal/misc_functions.h>
namespace CGAL #include <CGAL/number_utils.h>
{
namespace internal namespace CGAL {
{ namespace Surface_mesh_shortest_paths_3 {
namespace internal {
template<class Traits> template<class Traits>
class Cone_tree_node class Cone_tree_node
@ -62,33 +61,38 @@ private:
typedef typename Graph_traits::face_descriptor face_descriptor; typedef typename Graph_traits::face_descriptor face_descriptor;
typedef typename Graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename Graph_traits::halfedge_descriptor halfedge_descriptor;
typedef typename Graph_traits::vertex_descriptor vertex_descriptor; typedef typename Graph_traits::vertex_descriptor vertex_descriptor;
typedef typename CGAL::internal::Cone_expansion_event<Traits> Cone_expansion_event; typedef typename Surface_mesh_shortest_paths_3::internal::Cone_expansion_event<Traits> Cone_expansion_event;
private: private:
// These could be pulled back into a 'context' class to save space // These could be pulled back into a 'context' class to save space
Traits& m_traits; const Traits& m_traits;
Triangle_mesh& m_graph; const Triangle_mesh& m_graph;
halfedge_descriptor m_entryEdge; const halfedge_descriptor m_entryEdge;
Point_2 m_sourceImage; const Point_2 m_sourceImage;
Triangle_2 m_layoutFace; const Triangle_2 m_layoutFace;
FT m_pseudoSourceDistance; const FT m_pseudoSourceDistance;
Point_2 m_windowLeft; const Point_2 m_windowLeft;
Point_2 m_windowRight; const Point_2 m_windowRight;
size_t m_level; std::size_t m_level;
size_t m_treeId; std::size_t m_treeId;
Node_type m_nodeType; const Node_type m_nodeType;
Cone_tree_node* m_leftChild; Cone_tree_node* m_leftChild;
std::vector<Cone_tree_node*> m_middleChildren;
Cone_tree_node* m_rightChild; Cone_tree_node* m_rightChild;
std::vector<Cone_tree_node*> m_middleChildren;
Cone_tree_node* m_parent; Cone_tree_node* m_parent;
public:
Cone_expansion_event* m_pendingLeftSubtree;
Cone_expansion_event* m_pendingRightSubtree;
Cone_expansion_event* m_pendingMiddleSubtree;
private: private:
void on_child_link(Cone_tree_node* child) void on_child_link(Cone_tree_node* child)
{ {
@ -98,7 +102,9 @@ private:
} }
public: public:
Cone_tree_node(Traits& traits, Triangle_mesh& g, size_t treeId) Cone_tree_node(const Traits& traits,
const Triangle_mesh& g,
const std::size_t treeId)
: m_traits(traits) : m_traits(traits)
, m_graph(g) , m_graph(g)
, m_sourceImage(Point_2(CGAL::ORIGIN)) , m_sourceImage(Point_2(CGAL::ORIGIN))
@ -115,7 +121,10 @@ public:
{ {
} }
Cone_tree_node(Traits& traits, Triangle_mesh& g, size_t treeId, halfedge_descriptor entryEdge) Cone_tree_node(const Traits& traits,
const Triangle_mesh& g,
const std::size_t treeId,
const halfedge_descriptor entryEdge)
: m_traits(traits) : m_traits(traits)
, m_graph(g) , m_graph(g)
, m_entryEdge(entryEdge) , m_entryEdge(entryEdge)
@ -133,7 +142,15 @@ public:
{ {
} }
Cone_tree_node(Traits& traits, Triangle_mesh& g, halfedge_descriptor entryEdge, const Triangle_2& layoutFace, const Point_2& sourceImage, const FT& pseudoSourceDistance, const Point_2& windowLeft, const Point_2& windowRight, Node_type nodeType = INTERVAL) Cone_tree_node(const Traits& traits,
const Triangle_mesh& g,
const halfedge_descriptor entryEdge,
const Triangle_2& layoutFace,
const Point_2& sourceImage,
const FT& pseudoSourceDistance,
const Point_2& windowLeft,
const Point_2& windowRight,
const Node_type nodeType = INTERVAL)
: m_traits(traits) : m_traits(traits)
, m_graph(g) , m_graph(g)
, m_entryEdge(entryEdge) , m_entryEdge(entryEdge)
@ -151,12 +168,12 @@ public:
{ {
} }
size_t tree_id() const std::size_t tree_id() const
{ {
return m_treeId; return m_treeId;
} }
size_t level() const std::size_t level() const
{ {
return m_level; return m_level;
} }
@ -176,7 +193,7 @@ public:
return m_nodeType == ROOT; return m_nodeType == ROOT;
} }
Triangle_2 layout_face() const const Triangle_2& layout_face() const
{ {
return m_layoutFace; return m_layoutFace;
} }
@ -191,9 +208,9 @@ public:
return current_face() == Graph_traits::null_face(); return current_face() == Graph_traits::null_face();
} }
size_t edge_face_index() const std::size_t edge_face_index() const
{ {
return CGAL::internal::edge_index(entry_edge(), m_graph); return edge_index(entry_edge(), m_graph);
} }
halfedge_descriptor entry_edge() const halfedge_descriptor entry_edge() const
@ -216,7 +233,7 @@ public:
return target(next(m_entryEdge, m_graph), m_graph); return target(next(m_entryEdge, m_graph), m_graph);
} }
Point_2 source_image() const const Point_2& source_image() const
{ {
return m_sourceImage; return m_sourceImage;
} }
@ -229,7 +246,7 @@ public:
FT distance_to_root(const Point_2& point) const FT distance_to_root(const Point_2& point) const
{ {
typename Traits::Compute_squared_distance_2 csd2(m_traits.compute_squared_distance_2_object()); typename Traits::Compute_squared_distance_2 csd2(m_traits.compute_squared_distance_2_object());
return CGAL::internal::select_sqrt(csd2(point, m_sourceImage)) + m_pseudoSourceDistance; return CGAL::approximate_sqrt(csd2(point, m_sourceImage)) + m_pseudoSourceDistance;
} }
FT distance_from_source_to_root() const FT distance_from_source_to_root() const
@ -252,12 +269,12 @@ public:
return Ray_2(source_image(), m_windowRight); return Ray_2(source_image(), m_windowRight);
} }
Point_2 window_left() const const Point_2& window_left() const
{ {
return m_windowLeft; return m_windowLeft;
} }
Point_2 window_right() const const Point_2& window_right() const
{ {
return m_windowRight; return m_windowRight;
} }
@ -270,10 +287,13 @@ public:
bool inside_window(const Point_2& point) const bool inside_window(const Point_2& point) const
{ {
typename Traits::Orientation_2 orientation_2(m_traits.orientation_2_object()); typename Traits::Orientation_2 orientation_2(m_traits.orientation_2_object());
Point_2 sourceImagePoint(source_image()); Point_2 sourceImagePoint(source_image());
CGAL::Orientation leftOrientation = orientation_2(sourceImagePoint, m_windowLeft, point); CGAL::Orientation leftOrientation = orientation_2(sourceImagePoint, m_windowLeft, point);
CGAL::Orientation rightOrientation = orientation_2(sourceImagePoint, m_windowRight, point); CGAL::Orientation rightOrientation = orientation_2(sourceImagePoint, m_windowRight, point);
return (leftOrientation == CGAL::RIGHT_TURN || leftOrientation == CGAL::COLLINEAR) && (rightOrientation == CGAL::LEFT_TURN || rightOrientation == CGAL::COLLINEAR);
return (leftOrientation == CGAL::RIGHT_TURN || leftOrientation == CGAL::COLLINEAR) &&
(rightOrientation == CGAL::LEFT_TURN || rightOrientation == CGAL::COLLINEAR);
} }
Point_2 target_point() const Point_2 target_point() const
@ -289,25 +309,17 @@ public:
bool has_left_side() const bool has_left_side() const
{ {
typename Traits::Orientation_2 orientation_2(m_traits.orientation_2_object());
if (is_source_node()) if (is_source_node())
{ {
return true; return true;
} }
CGAL::Orientation orientation = orientation_2(source_image(), m_windowLeft, target_point()); return (m_traits.orientation_2_object()(source_image(), m_windowLeft, target_point()) != CGAL::LEFT_TURN);
return (orientation == CGAL::RIGHT_TURN || orientation == CGAL::COLLINEAR);
} }
bool has_right_side() const bool has_right_side() const
{ {
typename Traits::Orientation_2 orientation_2(m_traits.orientation_2_object()); return (m_traits.orientation_2_object()(source_image(), m_windowRight, target_point()) != CGAL::RIGHT_TURN);
CGAL::Orientation orientation = orientation_2(source_image(), m_windowRight, target_point());
return (orientation == CGAL::LEFT_TURN || orientation == CGAL::COLLINEAR);
} }
Segment_2 left_child_base_segment() const Segment_2 left_child_base_segment() const
@ -335,12 +347,12 @@ public:
return m_middleChildren.size() > 0; return m_middleChildren.size() > 0;
} }
size_t num_middle_children() const std::size_t num_middle_children() const
{ {
return m_middleChildren.size(); return m_middleChildren.size();
} }
Cone_tree_node* get_middle_child(size_t i) const Cone_tree_node* get_middle_child(const std::size_t i) const
{ {
return m_middleChildren.at(i); return m_middleChildren.at(i);
} }
@ -426,16 +438,10 @@ public:
{ {
return m_parent != nullptr && m_parent->m_rightChild == this; return m_parent != nullptr && m_parent->m_rightChild == this;
} }
public:
Cone_expansion_event* m_pendingLeftSubtree;
Cone_expansion_event* m_pendingRightSubtree;
Cone_expansion_event* m_pendingMiddleSubtree;
}; };
} // namespace internal } // namespace internal
} // namespace Surface_mesh_shortest_paths_3
} // namespace CGAL } // namespace CGAL
#endif // CGAL_SURFACE_MESH_SHORTEST_PATH_INTERNAL_CONE_TREE_H #endif // CGAL_SURFACE_MESH_SHORTEST_PATH_INTERNAL_CONE_TREE_H

View File

@ -29,41 +29,45 @@
#include <CGAL/boost/graph/iterator.h> #include <CGAL/boost/graph/iterator.h>
namespace CGAL { namespace CGAL {
namespace Surface_mesh_shortest_paths_3 {
namespace internal { namespace internal {
template <class Triangle_3, class Triangle_mesh, class VertexPointMap> template <class Triangle_3, class Triangle_mesh, class VertexPointMap>
Triangle_3 triangle_from_halfedge(typename boost::graph_traits<Triangle_mesh>::halfedge_descriptor edge, const Triangle_mesh& g, VertexPointMap vertexPointMap) Triangle_3 triangle_from_halfedge(typename boost::graph_traits<Triangle_mesh>::halfedge_descriptor edge,
const Triangle_mesh& g,
const VertexPointMap vertexPointMap)
{ {
typedef typename boost::graph_traits<Triangle_mesh>::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits<Triangle_mesh>::halfedge_descriptor halfedge_descriptor;
halfedge_descriptor e0 = edge; const halfedge_descriptor e0 = edge;
halfedge_descriptor e1 = next(edge, g); const halfedge_descriptor e1 = next(edge, g);
return Triangle_3(get(vertexPointMap, source(e0, g)), get(vertexPointMap, target(e0, g)), get(vertexPointMap, target(e1, g))); return Triangle_3(get(vertexPointMap, source(e0, g)),
get(vertexPointMap, target(e0, g)),
get(vertexPointMap, target(e1, g)));
} }
template <class Triangle_3, class Triangle_mesh> template <class Triangle_3, class Triangle_mesh>
Triangle_3 triangle_from_halfedge(typename boost::graph_traits<Triangle_mesh>::halfedge_descriptor edge, const Triangle_mesh& g) Triangle_3 triangle_from_halfedge(typename boost::graph_traits<Triangle_mesh>::halfedge_descriptor edge,
const Triangle_mesh& g)
{ {
return triangle_from_halfedge<Triangle_3, Triangle_mesh, typename boost::property_map<Triangle_mesh, boost::vertex_point_t>::type>(edge, g, get(boost::vertex_point, g)); return triangle_from_halfedge<Triangle_3>(edge, g, get(boost::vertex_point, g));
} }
template <class Triangle_mesh> template <class Triangle_mesh>
size_t edge_index(typename boost::graph_traits<Triangle_mesh>::halfedge_descriptor he, Triangle_mesh& p) std::size_t edge_index(typename boost::graph_traits<Triangle_mesh>::halfedge_descriptor he,
const Triangle_mesh& p)
{ {
typedef typename boost::graph_traits<Triangle_mesh> Graph_traits; typedef typename boost::graph_traits<Triangle_mesh> Graph_traits;
typedef typename Graph_traits::face_descriptor face_descriptor; typedef typename Graph_traits::face_descriptor face_descriptor;
typedef typename Graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename Graph_traits::halfedge_descriptor halfedge_descriptor;
face_descriptor f = face(he, p); const face_descriptor f = face(he, p);
halfedge_descriptor start = halfedge(f, p); const halfedge_descriptor start = halfedge(f, p);
halfedge_descriptor current = start; halfedge_descriptor current = start;
size_t count = 0; std::size_t count = 0;
while (current != he) while (current != he)
{ {
current = next(current, p); current = next(current, p);
@ -73,28 +77,8 @@ size_t edge_index(typename boost::graph_traits<Triangle_mesh>::halfedge_descript
return count; return count;
} }
template <class FT>
FT internal_sqrt(const FT& x, CGAL::Tag_true)
{
return CGAL::sqrt(x);
}
template <class FT>
FT internal_sqrt(const FT& x, CGAL::Tag_false)
{
return FT(std::sqrt(CGAL::to_double(x)));
}
template <class FT>
FT select_sqrt(const FT& x)
{
typedef ::CGAL::Algebraic_structure_traits<FT> AST;
static const bool has_sqrt = ! ::boost::is_same< ::CGAL::Null_functor, typename AST::Sqrt >::value;
return internal_sqrt(x, ::CGAL::Boolean_tag<has_sqrt>());
}
} // namespace internal } // namespace internal
} // namespace Surface_mesh_shortest_paths_3
} // namespace CGAL } // namespace CGAL
#endif // CGAL_SURFACE_MESH_SHORTEST_PATH_INTERNAL_MISC_H #endif // CGAL_SURFACE_MESH_SHORTEST_PATH_INTERNAL_MISC_H

View File

@ -14,6 +14,8 @@ create_single_source_cgal_program( "Surface_mesh_shortest_path_test_1.cpp" )
create_single_source_cgal_program( "Surface_mesh_shortest_path_test_2.cpp" ) create_single_source_cgal_program( "Surface_mesh_shortest_path_test_2.cpp" )
create_single_source_cgal_program( "Surface_mesh_shortest_path_test_3.cpp" ) create_single_source_cgal_program( "Surface_mesh_shortest_path_test_3.cpp" )
create_single_source_cgal_program( "Surface_mesh_shortest_path_test_4.cpp" ) create_single_source_cgal_program( "Surface_mesh_shortest_path_test_4.cpp" )
create_single_source_cgal_program( "Surface_mesh_shortest_path_test_5.cpp" )
create_single_source_cgal_program( "Surface_mesh_shortest_path_test_6.cpp" )
create_single_source_cgal_program( "Surface_mesh_shortest_path_traits_test.cpp" ) create_single_source_cgal_program( "Surface_mesh_shortest_path_traits_test.cpp" )
# Link with Boost.ProgramOptions (optional) # Link with Boost.ProgramOptions (optional)

View File

@ -213,7 +213,7 @@ void test_simple_saddle_vertex_mesh()
// Now test an internal face location sequence // Now test an internal face location sequence
halfedge_descriptor firstCrossing = CGAL::halfedge(vertexHandles[4], vertexHandles[7], P).first; halfedge_descriptor firstCrossing = CGAL::halfedge(vertexHandles[4], vertexHandles[7], P).first;
size_t edgeIndex = CGAL::internal::edge_index(firstCrossing, P); size_t edgeIndex = CGAL::Surface_mesh_shortest_paths_3::internal::edge_index(firstCrossing, P);
Barycentric_coordinates location = construct_barycentric_coordinates(0.25, 0.5, 0.25); Barycentric_coordinates location = construct_barycentric_coordinates(0.25, 0.5, 0.25);
@ -289,6 +289,7 @@ void test_simple_saddle_vertex_mesh()
CHECK_CLOSE(result.first, expectedDistances2[i], Kernel::FT(0.0001)); CHECK_CLOSE(result.first, expectedDistances2[i], Kernel::FT(0.0001));
assert(result.second == expectedSources2[i]); assert(result.second == expectedSources2[i]);
CGAL_USE(expectedSources2);
++currentVertex; ++currentVertex;
} }

View File

@ -88,7 +88,7 @@ int main(int argc, char* argv[])
size_t faceIndex = random.get_int(0, static_cast<int>(facesList.size())); size_t faceIndex = random.get_int(0, static_cast<int>(facesList.size()));
face_descriptor face = facesList[faceIndex]; face_descriptor face = facesList[faceIndex];
Triangle_3 faceTriangle = CGAL::internal::triangle_from_halfedge<Triangle_3, Polyhedron_3, VPM>(halfedge(face, polyhedron), polyhedron, vertexPointMap); Triangle_3 faceTriangle = CGAL::Surface_mesh_shortest_paths_3::internal::triangle_from_halfedge<Triangle_3, Polyhedron_3, VPM>(halfedge(face, polyhedron), polyhedron, vertexPointMap);
Barycentric_coordinates location = CGAL::test::random_coordinates<Traits>(random); Barycentric_coordinates location = CGAL::test::random_coordinates<Traits>(random);

View File

@ -94,7 +94,7 @@ int main(int argc, char* argv[])
size_t faceIndex = random.get_int(0, static_cast<int>(facesList.size())); size_t faceIndex = random.get_int(0, static_cast<int>(facesList.size()));
face_descriptor face = facesList[faceIndex]; face_descriptor face = facesList[faceIndex];
Triangle_3 faceTriangle = CGAL::internal::triangle_from_halfedge<Triangle_3, Polyhedron_3, VPM>(halfedge(face, polyhedron), polyhedron, vertexPointMap); Triangle_3 faceTriangle = CGAL::Surface_mesh_shortest_paths_3::internal::triangle_from_halfedge<Triangle_3, Polyhedron_3, VPM>(halfedge(face, polyhedron), polyhedron, vertexPointMap);
Barycentric_coordinates location = CGAL::test::random_coordinates<Traits>(random); Barycentric_coordinates location = CGAL::test::random_coordinates<Traits>(random);
@ -146,6 +146,7 @@ int main(int argc, char* argv[])
Ray_3 outsideRay(maxPoint + (awayDir * FT(0.2)), maxPoint + (awayDir * FT(1.0))); Ray_3 outsideRay(maxPoint + (awayDir * FT(0.2)), maxPoint + (awayDir * FT(1.0)));
Surface_mesh_shortest_path::Face_location emptyFaceLocation = shortestPaths.locate<AABB_face_graph_traits>(outsideRay); Surface_mesh_shortest_path::Face_location emptyFaceLocation = shortestPaths.locate<AABB_face_graph_traits>(outsideRay);
CGAL_USE(emptyFaceLocation);
assert(Graph_traits::null_face() == emptyFaceLocation.first); assert(Graph_traits::null_face() == emptyFaceLocation.first);

View File

@ -29,11 +29,8 @@ int main(int argc, char* argv[])
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef CGAL::Polyhedron_3<Kernel, CGAL::Polyhedron_items_with_id_3> Polyhedron_3; typedef CGAL::Polyhedron_3<Kernel, CGAL::Polyhedron_items_with_id_3> Polyhedron_3;
typedef CGAL::Surface_mesh_shortest_path_traits<Kernel, Polyhedron_3> Traits; typedef CGAL::Surface_mesh_shortest_path_traits<Kernel, Polyhedron_3> Traits;
typedef Traits::Barycentric_coordinates Barycentric_coordinates;
typedef Traits::FT FT; typedef Traits::FT FT;
typedef boost::graph_traits<Polyhedron_3> Graph_traits; typedef boost::graph_traits<Polyhedron_3> Graph_traits;
typedef Graph_traits::vertex_descriptor vertex_descriptor;
typedef Graph_traits::vertex_iterator vertex_iterator;
typedef Graph_traits::face_descriptor face_descriptor; typedef Graph_traits::face_descriptor face_descriptor;
typedef Graph_traits::face_iterator face_iterator; typedef Graph_traits::face_iterator face_iterator;
typedef CGAL::Surface_mesh_shortest_path<Traits> Surface_mesh_shortest_path; typedef CGAL::Surface_mesh_shortest_path<Traits> Surface_mesh_shortest_path;
@ -47,7 +44,6 @@ int main(int argc, char* argv[])
std::string mesh(argv[1]); std::string mesh(argv[1]);
int randSeed = 4983304; int randSeed = 4983304;
const size_t numTests = 15;
if (argc > 2) if (argc > 2)
{ {
@ -69,6 +65,10 @@ int main(int argc, char* argv[])
HIM halfedgeIndexMap(get(boost::halfedge_index, polyhedron)); HIM halfedgeIndexMap(get(boost::halfedge_index, polyhedron));
FIM faceIndexMap(get(boost::face_index, polyhedron)); FIM faceIndexMap(get(boost::face_index, polyhedron));
CGAL_USE(vertexIndexMap);
CGAL_USE(halfedgeIndexMap);
CGAL_USE(faceIndexMap);
face_iterator facesStart; face_iterator facesStart;
face_iterator facesEnd; face_iterator facesEnd;
@ -92,12 +92,12 @@ int main(int argc, char* argv[])
for (size_t i = 0; i < numInitialLocations; ++i) for (size_t i = 0; i < numInitialLocations; ++i)
{ {
size_t faceId = rand.get_int(0, faces.size()); size_t faceId = static_cast<std::size_t>(rand.get_int(0, static_cast<int>(faces.size())));
sourcePoints.push_back(Face_location(faces[faceId], CGAL::test::random_coordinates<Traits>(rand))); sourcePoints.push_back(Face_location(faces[faceId], CGAL::test::random_coordinates<Traits>(rand)));
shortestPaths.add_source_point(sourcePoints.back().first, sourcePoints.back().second); shortestPaths.add_source_point(sourcePoints.back().first, sourcePoints.back().second);
} }
BOOST_CHECK_EQUAL(numInitialLocations, shortestPaths.number_of_source_points()); CHECK_EQUAL(numInitialLocations, shortestPaths.number_of_source_points());
size_t checkNumLocations = 0; size_t checkNumLocations = 0;
@ -107,18 +107,16 @@ int main(int argc, char* argv[])
++checkNumLocations; ++checkNumLocations;
} }
BOOST_CHECK_EQUAL(checkNumLocations, shortestPaths.number_of_source_points()); CHECK_EQUAL(checkNumLocations, shortestPaths.number_of_source_points());
for (Surface_mesh_shortest_path::Source_point_iterator it = shortestPaths.source_points_begin(); it != shortestPaths.source_points_end(); ++it) for (Surface_mesh_shortest_path::Source_point_iterator it = shortestPaths.source_points_begin(); it != shortestPaths.source_points_end(); ++it)
{ {
Surface_mesh_shortest_path::Shortest_path_result result = shortestPaths.shortest_distance_to_source_points(it->first, it->second); Surface_mesh_shortest_path::Shortest_path_result result = shortestPaths.shortest_distance_to_source_points(it->first, it->second);
BOOST_CHECK_CLOSE(FT(0.0), result.first, FT(0.000001)); CHECK_CLOSE(FT(0.0), result.first, FT(0.000001));
assert(result.second == it); assert(result.second == it);
} }
size_t currentCounter = 0;
// Then, remove half of them // Then, remove half of them
for (size_t i = 0; i < handles.size(); ++i) for (size_t i = 0; i < handles.size(); ++i)
@ -129,7 +127,7 @@ int main(int argc, char* argv[])
} }
} }
BOOST_CHECK_EQUAL(numInitialLocations / 2, shortestPaths.number_of_source_points()); CHECK_EQUAL(numInitialLocations / 2, shortestPaths.number_of_source_points());
// and ensure that they are indeed removed // and ensure that they are indeed removed
for (size_t i = 0; i < sourcePoints.size(); ++i) for (size_t i = 0; i < sourcePoints.size(); ++i)
@ -138,12 +136,16 @@ int main(int argc, char* argv[])
if (i % 2 != 0) if (i % 2 != 0)
{ {
BOOST_CHECK_CLOSE(FT(0.0), result.first, FT(0.000001)); CHECK_CLOSE(FT(0.0), result.first, FT(0.000001));
assert(handles[i] == result.second); assert(handles[i] == result.second);
} }
else else
{ {
BOOST_CHECK_MESSAGE(result.first < FT(0.0) || result.first > FT(0.00001), "Incorrect resulting distance: " << result.first); if ( !(result.first < FT(0.0) || result.first > FT(0.00001) ) )
{
std::cerr << "Incorrect resulting distance: " << result.first << "\n";
return 1;
}
} }
} }
@ -172,12 +174,16 @@ int main(int argc, char* argv[])
if (i % 3 != 0) if (i % 3 != 0)
{ {
BOOST_CHECK_CLOSE(FT(0.0), result.first, FT(0.000001)); CHECK_CLOSE(FT(0.0), result.first, FT(0.000001));
assert(handles[i] == result.second); assert(handles[i] == result.second);
} }
else else
{ {
BOOST_CHECK_MESSAGE(result.first < FT(0.0) || result.first > FT(0.00001), "Resulted distance: " << result.first); if( !(result.first < FT(0.0) || result.first > FT(0.00001)) )
{
std::cerr << "Resulted distance: " << result.first << "\n";
return 1;
}
} }
} }
return 0; return 0;

View File

@ -0,0 +1,36 @@
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Surface_mesh_shortest_path.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef CGAL::Surface_mesh<Kernel::Point_3> Triangle_mesh;
typedef CGAL::Surface_mesh_shortest_path_traits<Kernel, Triangle_mesh> Traits;
typedef CGAL::Surface_mesh_shortest_path<Traits> Surface_mesh_shortest_path;
typedef boost::graph_traits<Triangle_mesh> Graph_traits;
typedef Graph_traits::vertex_iterator vertex_iterator;
typedef Graph_traits::face_iterator face_iterator;
int main()
{
CGAL::Surface_mesh<Kernel::Point_3> mesh;
std::ifstream input("data/test_mesh_6.off");
input >> mesh;
input.close();
for (Triangle_mesh::Vertex_index v1 : vertices(mesh))
for (Triangle_mesh::Vertex_index v2 : vertices(mesh))
{
Surface_mesh_shortest_path shortest_paths(mesh);
shortest_paths.add_source_point(v1);
double dist = shortest_paths.shortest_distance_to_source_points(v2).first;
assert (dist==0 || v1!=v2);
CGAL_USE(dist);
}
return 0;
}

View File

@ -269,6 +269,7 @@ void detect_is_saddle_vertex()
Traits traits; Traits traits;
Traits::Is_saddle_vertex is_saddle_vertex(traits.is_saddle_vertex_object()); Traits::Is_saddle_vertex is_saddle_vertex(traits.is_saddle_vertex_object());
CGAL_USE(is_saddle_vertex);
std::ifstream inFile("data/saddle_vertex_mesh.off"); std::ifstream inFile("data/saddle_vertex_mesh.off");

View File

@ -70,7 +70,7 @@ struct TestMeshProgramInstance
TestMeshProgramInstance() TestMeshProgramInstance()
{ {
debugMode = false; debugMode = false;
randomizer = NULL; randomizer = nullptr;
numVertices = 0; numVertices = 0;
numIterations = 1; numIterations = 1;
} }

View File

@ -2,6 +2,9 @@
template <typename FT, typename FT2> template <typename FT, typename FT2>
void CHECK_EQUAL(const FT& a, const FT2& b) void CHECK_EQUAL(const FT& a, const FT2& b)
{ {
if (a != b)
std::cerr << "ERROR: a (" << a << ") is not equal to b (" << b << ").\n";
assert(a == b); assert(a == b);
} }

View File

@ -0,0 +1,60 @@
OFF
25 32 64
0.000000000000000e+00 0.000000000000000e+00 1.000000000000000e+00
2.500000000000000e-01 0.000000000000000e+00 1.000000000000000e+00
5.000000000000000e-01 0.000000000000000e+00 1.000000000000000e+00
7.500000000000000e-01 0.000000000000000e+00 1.000000000000000e+00
1.000000000000000e+00 0.000000000000000e+00 1.000000000000000e+00
0.000000000000000e+00 2.500000000000000e-01 1.000000000000000e+00
2.500000000000000e-01 2.500000000000000e-01 1.000000000000000e+00
5.000000000000000e-01 2.500000000000000e-01 1.000000000000000e+00
7.500000000000000e-01 2.500000000000000e-01 1.000000000000000e+00
1.000000000000000e+00 2.500000000000000e-01 1.000000000000000e+00
0.000000000000000e+00 5.000000000000000e-01 1.000000000000000e+00
2.500000000000000e-01 5.000000000000000e-01 1.000000000000000e+00
5.000000000000000e-01 5.000000000000000e-01 1.000000000000000e+00
7.500000000000000e-01 5.000000000000000e-01 1.000000000000000e+00
1.000000000000000e+00 5.000000000000000e-01 1.000000000000000e+00
0.000000000000000e+00 7.500000000000000e-01 1.000000000000000e+00
2.500000000000000e-01 7.500000000000000e-01 1.000000000000000e+00
5.000000000000000e-01 7.500000000000000e-01 1.000000000000000e+00
7.500000000000000e-01 7.500000000000000e-01 1.000000000000000e+00
1.000000000000000e+00 7.500000000000000e-01 1.000000000000000e+00
0.000000000000000e+00 1.000000000000000e+00 1.000000000000000e+00
2.500000000000000e-01 1.000000000000000e+00 1.000000000000000e+00
5.000000000000000e-01 1.000000000000000e+00 1.000000000000000e+00
7.500000000000000e-01 1.000000000000000e+00 1.000000000000000e+00
1.000000000000000e+00 1.000000000000000e+00 1.000000000000000e+00
3 0 1 6
3 0 6 5
3 5 6 11
3 5 11 10
3 10 11 16
3 10 16 15
3 15 16 21
3 15 21 20
3 1 2 7
3 1 7 6
3 6 7 12
3 6 12 11
3 11 12 17
3 11 17 16
3 16 17 22
3 16 22 21
3 2 3 8
3 2 8 7
3 7 8 13
3 7 13 12
3 12 13 18
3 12 18 17
3 17 18 23
3 17 23 22
3 3 4 9
3 3 9 8
3 8 9 14
3 8 14 13
3 13 14 19
3 13 19 18
3 18 19 24
3 18 24 23

View File

@ -2,7 +2,10 @@ Algebraic_foundations
Circulator Circulator
Hash_map Hash_map
Installation Installation
Interval_support
Kernel_23 Kernel_23
Modular_arithmetic
Number_types
Profiling_tools Profiling_tools
STL_Extension STL_Extension
Stream_support Stream_support

View File

@ -1,9 +1,2 @@
Algebraic_foundations
GraphicsView
Installation Installation
Kernel_23
Number_types
Profiling_tools
STL_Extension STL_Extension
Stream_support
Three

12
ccpp.yml Normal file
View File

@ -0,0 +1,12 @@
name: C/C++ CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: configure all
run: cmake -DWITH_examples=ON -DWITH_tests=ON -DWITH_demos=ON .