Merge branch '5.1.x-branch' into 5.2.x-branch

This commit is contained in:
Laurent Rineau 2021-02-18 15:19:05 +01:00
commit fa1a355751
23 changed files with 250 additions and 163 deletions

View File

@ -302,13 +302,13 @@ to_interval( const Real_embeddable& x) {
} }
template <typename NT> template <typename NT>
NT approximate_sqrt(const NT& nt, CGAL::Field_tag) NT approximate_sqrt(const NT& nt, CGAL::Null_functor)
{ {
return NT(sqrt(CGAL::to_double(nt))); return NT(sqrt(CGAL::to_double(nt)));
} }
template <typename NT> template <typename NT, typename Sqrt>
NT approximate_sqrt(const NT& nt, CGAL::Field_with_sqrt_tag) NT approximate_sqrt(const NT& nt, Sqrt sqrt)
{ {
return sqrt(nt); return sqrt(nt);
} }
@ -316,9 +316,12 @@ NT approximate_sqrt(const NT& nt, CGAL::Field_with_sqrt_tag)
template <typename NT> template <typename NT>
NT approximate_sqrt(const NT& nt) NT approximate_sqrt(const NT& nt)
{ {
// the initial version of this function was using Algebraic_category
// for the dispatch but some ring type (like Gmpz) provides a Sqrt
// functor even if not being Field_with_sqrt.
typedef CGAL::Algebraic_structure_traits<NT> AST; typedef CGAL::Algebraic_structure_traits<NT> AST;
typedef typename AST::Algebraic_category Algebraic_category; typedef typename AST::Sqrt Sqrt;
return approximate_sqrt(nt, Algebraic_category()); return approximate_sqrt(nt, Sqrt());
} }
CGAL_NTS_END_NAMESPACE CGAL_NTS_END_NAMESPACE

View File

@ -246,8 +246,8 @@ bisector_of_linesC2(const FT &pa, const FT &pb, const FT &pc,
FT &a, FT &b, FT &c) FT &a, FT &b, FT &c)
{ {
// We normalize the equations of the 2 lines, and we then add them. // We normalize the equations of the 2 lines, and we then add them.
FT n1 = CGAL_NTS sqrt(CGAL_NTS square(pa) + CGAL_NTS square(pb)); FT n1 = CGAL_NTS approximate_sqrt( FT(CGAL_NTS square(pa) + CGAL_NTS square(pb)) );
FT n2 = CGAL_NTS sqrt(CGAL_NTS square(qa) + CGAL_NTS square(qb)); FT n2 = CGAL_NTS approximate_sqrt( FT(CGAL_NTS square(qa) + CGAL_NTS square(qb)) );
a = n2 * pa + n1 * qa; a = n2 * pa + n1 * qa;
b = n2 * pb + n1 * qb; b = n2 * pb + n1 * qb;
c = n2 * pc + n1 * qc; c = n2 * pc + n1 * qc;

View File

@ -366,10 +366,10 @@ bisector_of_planesC3(const FT &pa, const FT &pb, const FT &pc, const FT &pd,
FT &a, FT &b, FT &c, FT &d) FT &a, FT &b, FT &c, FT &d)
{ {
// We normalize the equations of the 2 planes, and we then add them. // We normalize the equations of the 2 planes, and we then add them.
FT n1 = CGAL_NTS sqrt(CGAL_NTS square(pa) + CGAL_NTS square(pb) + FT n1 = CGAL_NTS approximate_sqrt( FT(CGAL_NTS square(pa) + CGAL_NTS square(pb) +
CGAL_NTS square(pc)); CGAL_NTS square(pc)) );
FT n2 = CGAL_NTS sqrt(CGAL_NTS square(qa) + CGAL_NTS square(qb) + FT n2 = CGAL_NTS approximate_sqrt( FT(CGAL_NTS square(qa) + CGAL_NTS square(qb) +
CGAL_NTS square(qc)); CGAL_NTS square(qc)) );
a = n2 * pa + n1 * qa; a = n2 * pa + n1 * qa;
b = n2 * pb + n1 * qb; b = n2 * pb + n1 * qb;
c = n2 * pc + n1 * qc; c = n2 * pc + n1 * qc;

View File

@ -154,6 +154,10 @@ executables should be linked with the CMake imported target
The \sc{libpointmatcher} web site is <A The \sc{libpointmatcher} web site is <A
HREF="https://github.com/ethz-asl/libpointmatcher">`https://github.com/ethz-asl/libpointmatcher`</A>. HREF="https://github.com/ethz-asl/libpointmatcher">`https://github.com/ethz-asl/libpointmatcher`</A>.
\attention On Windows, we only support version 1.3.1 of PointMatcher with version 3.3.7 of Eigen, with some changes to the recipe at
`https://github.com/ethz-asl/libpointmatcher/blob/master/doc/CompilationWindows.md`:`NABO_INCLUDE_DIR` becomes `libnabo_INCLUDE_DIRS`
and `NABO_LIBRARY` becomes `libnabo_LIBRARIES` in the "Build libpointmatcher" section.
\subsection thirdpartyLeda LEDA \subsection thirdpartyLeda LEDA
<b>Version 6.2 or later</b> <b>Version 6.2 or later</b>

View File

@ -3,6 +3,7 @@
#include <CGAL/config.h> #include <CGAL/config.h>
#include <CGAL/Bbox_2.h> #include <CGAL/Bbox_2.h>
#include <CGAL/algorithm.h>
#include <CGAL/Timer.h> #include <CGAL/Timer.h>
#include <vector> #include <vector>
#include <utility> #include <utility>
@ -96,7 +97,7 @@ class Constraints_loader {
for(Points_iterator it = points.begin(); it != points.end(); ++it) { for(Points_iterator it = points.begin(); it != points.end(); ++it) {
indices.push_back(it); indices.push_back(it);
} }
std::random_shuffle(indices.begin(), indices.end()); CGAL::cpp98::random_shuffle(indices.begin(), indices.end());
CGAL::spatial_sort(indices.begin(), indices.end(), CGAL::spatial_sort(indices.begin(), indices.end(),
sort_traits); sort_traits);

View File

@ -3,6 +3,7 @@
#include <CGAL/config.h> #include <CGAL/config.h>
#include <CGAL/Bbox_2.h> #include <CGAL/Bbox_2.h>
#include <CGAL/algorithm.h>
#include <CGAL/Timer.h> #include <CGAL/Timer.h>
#include <vector> #include <vector>
#include <utility> #include <utility>
@ -96,7 +97,7 @@ class Constraints_loader {
for(Points_iterator it = points.begin(); it != points.end(); ++it) { for(Points_iterator it = points.begin(); it != points.end(); ++it) {
indices.push_back(it); indices.push_back(it);
} }
std::random_shuffle(indices.begin(), indices.end()); CGAL::cpp98::random_shuffle(indices.begin(), indices.end());
CGAL::spatial_sort(indices.begin(), indices.end(), CGAL::spatial_sort(indices.begin(), indices.end(),
sort_traits); sort_traits);

View File

@ -883,10 +883,13 @@ void Camera::interpolateTo(const Frame &fr, qreal duration) {
imprecision along the viewing direction. */ imprecision along the viewing direction. */
CGAL_INLINE_FUNCTION CGAL_INLINE_FUNCTION
Vec Camera::pointUnderPixel(const QPoint &pixel, bool &found) const { Vec Camera::pointUnderPixel(const QPoint &pixel, bool &found) const {
float depth; float depth = 2.0;
// Qt uses upper corner for its origin while GL uses the lower corner. // Qt uses upper corner for its origin while GL uses the lower corner.
dynamic_cast<QOpenGLFunctions*>(parent())->glReadPixels(pixel.x(), screenHeight() - 1 - pixel.y(), 1, 1, if(auto p = dynamic_cast<QOpenGLFunctions*>(parent()))
{
p->glReadPixels(pixel.x(), screenHeight() - 1 - pixel.y(), 1, 1,
GL_DEPTH_COMPONENT, GL_FLOAT, &depth); GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
}
found = depth < 1.0; found = depth < 1.0;
Vec point(pixel.x(), pixel.y(), depth); Vec point(pixel.x(), pixel.y(), depth);
point = unprojectedCoordinatesOf(point); point = unprojectedCoordinatesOf(point);

View File

@ -738,7 +738,7 @@ void CGAL::QGLViewer::setDefaultMouseBindings() {
(mh == qglviewer::FRAME) ? frameKeyboardModifiers : cameraKeyboardModifiers; (mh == qglviewer::FRAME) ? frameKeyboardModifiers : cameraKeyboardModifiers;
setMouseBinding(modifiers, ::Qt::LeftButton, mh, qglviewer::ROTATE); setMouseBinding(modifiers, ::Qt::LeftButton, mh, qglviewer::ROTATE);
setMouseBinding(modifiers, ::Qt::MidButton, mh, qglviewer::ZOOM); setMouseBinding(modifiers, ::Qt::MiddleButton, mh, qglviewer::ZOOM);
setMouseBinding(modifiers, ::Qt::RightButton, mh, qglviewer::TRANSLATE); setMouseBinding(modifiers, ::Qt::RightButton, mh, qglviewer::TRANSLATE);
setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, mh, qglviewer::SCREEN_ROTATE); setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, mh, qglviewer::SCREEN_ROTATE);
@ -748,7 +748,7 @@ void CGAL::QGLViewer::setDefaultMouseBindings() {
setWheelBinding(::Qt::Key_Z, ::Qt::NoModifier, qglviewer::CAMERA, qglviewer::ZOOM_FOV); setWheelBinding(::Qt::Key_Z, ::Qt::NoModifier, qglviewer::CAMERA, qglviewer::ZOOM_FOV);
// Z o o m o n r e g i o n // Z o o m o n r e g i o n
setMouseBinding(::Qt::ShiftModifier, ::Qt::MidButton, qglviewer::CAMERA, qglviewer::ZOOM_ON_REGION); setMouseBinding(::Qt::ShiftModifier, ::Qt::MiddleButton, qglviewer::CAMERA, qglviewer::ZOOM_ON_REGION);
// S e l e c t // S e l e c t
setMouseBinding(::Qt::ShiftModifier, ::Qt::LeftButton, qglviewer::SELECT); setMouseBinding(::Qt::ShiftModifier, ::Qt::LeftButton, qglviewer::SELECT);
@ -756,7 +756,7 @@ void CGAL::QGLViewer::setDefaultMouseBindings() {
setMouseBinding(::Qt::ShiftModifier, ::Qt::RightButton, qglviewer::RAP_FROM_PIXEL); setMouseBinding(::Qt::ShiftModifier, ::Qt::RightButton, qglviewer::RAP_FROM_PIXEL);
// D o u b l e c l i c k // D o u b l e c l i c k
setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, qglviewer::ALIGN_CAMERA, true); setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, qglviewer::ALIGN_CAMERA, true);
setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, qglviewer::SHOW_ENTIRE_SCENE, true); setMouseBinding(::Qt::NoModifier, ::Qt::MiddleButton, qglviewer::SHOW_ENTIRE_SCENE, true);
setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, qglviewer::CENTER_SCENE, true); setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, qglviewer::CENTER_SCENE, true);
setMouseBinding(frameKeyboardModifiers, ::Qt::LeftButton, qglviewer::ALIGN_FRAME, true); setMouseBinding(frameKeyboardModifiers, ::Qt::LeftButton, qglviewer::ALIGN_FRAME, true);
@ -1223,7 +1223,7 @@ static QString mouseButtonsString(::Qt::MouseButtons b) {
result += CGAL::QGLViewer::tr("Left", "left mouse button"); result += CGAL::QGLViewer::tr("Left", "left mouse button");
addAmpersand = true; addAmpersand = true;
} }
if (b & ::Qt::MidButton) { if (b & ::Qt::MiddleButton) {
if (addAmpersand) if (addAmpersand)
result += " & "; result += " & ";
result += CGAL::QGLViewer::tr("Middle", "middle mouse button"); result += CGAL::QGLViewer::tr("Middle", "middle mouse button");
@ -1760,7 +1760,7 @@ Mouse tab.
\c ::Qt::AltModifier, \c ::Qt::ShiftModifier, \c ::Qt::MetaModifier). Possibly \c ::Qt::AltModifier, \c ::Qt::ShiftModifier, \c ::Qt::MetaModifier). Possibly
combined using the \c "|" operator. combined using the \c "|" operator.
\p button is one of the ::Qt::MouseButtons (\c ::Qt::LeftButton, \c ::Qt::MidButton, \p button is one of the ::Qt::MouseButtons (\c ::Qt::LeftButton, \c ::Qt::MiddleButton,
\c ::Qt::RightButton...). \c ::Qt::RightButton...).
\p doubleClick indicates whether or not the user has to double click this button \p doubleClick indicates whether or not the user has to double click this button
@ -3037,27 +3037,27 @@ void CGAL::QGLViewer::toggleCameraMode() {
camera()->frame()->stopSpinning(); camera()->frame()->stopSpinning();
setMouseBinding(modifiers, ::Qt::LeftButton, qglviewer::CAMERA, qglviewer::MOVE_FORWARD); setMouseBinding(modifiers, ::Qt::LeftButton, qglviewer::CAMERA, qglviewer::MOVE_FORWARD);
setMouseBinding(modifiers, ::Qt::MidButton, qglviewer::CAMERA, qglviewer::LOOK_AROUND); setMouseBinding(modifiers, ::Qt::MiddleButton, qglviewer::CAMERA, qglviewer::LOOK_AROUND);
setMouseBinding(modifiers, ::Qt::RightButton, qglviewer::CAMERA, qglviewer::MOVE_BACKWARD); setMouseBinding(modifiers, ::Qt::RightButton, qglviewer::CAMERA, qglviewer::MOVE_BACKWARD);
setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, qglviewer::CAMERA, qglviewer::ROLL); setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, qglviewer::CAMERA, qglviewer::ROLL);
setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, qglviewer::NO_CLICK_ACTION, true); setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, qglviewer::NO_CLICK_ACTION, true);
setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, qglviewer::NO_CLICK_ACTION, true); setMouseBinding(::Qt::NoModifier, ::Qt::MiddleButton, qglviewer::NO_CLICK_ACTION, true);
setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, qglviewer::NO_CLICK_ACTION, true); setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, qglviewer::NO_CLICK_ACTION, true);
setWheelBinding(modifiers, qglviewer::CAMERA, qglviewer::MOVE_FORWARD); setWheelBinding(modifiers, qglviewer::CAMERA, qglviewer::MOVE_FORWARD);
} else { } else {
// Should stop flyTimer. But unlikely and not easy. // Should stop flyTimer. But unlikely and not easy.
setMouseBinding(modifiers, ::Qt::LeftButton, qglviewer::CAMERA, qglviewer::ROTATE); setMouseBinding(modifiers, ::Qt::LeftButton, qglviewer::CAMERA, qglviewer::ROTATE);
setMouseBinding(modifiers, ::Qt::MidButton, qglviewer::CAMERA, qglviewer::ZOOM); setMouseBinding(modifiers, ::Qt::MiddleButton, qglviewer::CAMERA, qglviewer::ZOOM);
setMouseBinding(modifiers, ::Qt::RightButton, qglviewer::CAMERA, qglviewer::TRANSLATE); setMouseBinding(modifiers, ::Qt::RightButton, qglviewer::CAMERA, qglviewer::TRANSLATE);
setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, qglviewer::CAMERA, setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, qglviewer::CAMERA,
qglviewer::SCREEN_ROTATE); qglviewer::SCREEN_ROTATE);
setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, qglviewer::ALIGN_CAMERA, true); setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, qglviewer::ALIGN_CAMERA, true);
setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, qglviewer::SHOW_ENTIRE_SCENE, true); setMouseBinding(::Qt::NoModifier, ::Qt::MiddleButton, qglviewer::SHOW_ENTIRE_SCENE, true);
setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, qglviewer::CENTER_SCENE, true); setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, qglviewer::CENTER_SCENE, true);
setWheelBinding(modifiers, qglviewer::CAMERA, qglviewer::ZOOM); setWheelBinding(modifiers, qglviewer::CAMERA, qglviewer::ZOOM);

View File

@ -1,7 +1,16 @@
if(libpointmatcher_FOUND AND NOT TARGET CGAL::pointmatcher_support) if(libpointmatcher_FOUND AND NOT TARGET CGAL::pointmatcher_support)
find_package(Boost COMPONENTS thread filesystem system program_options date_time chrono)
if(Boost_chrono_FOUND
AND Boost_thread_FOUND
AND Boost_filesystem_FOUND
AND Boost_system_FOUND
AND Boost_program_options_FOUND
AND Boost_date_time_FOUND)
add_library(CGAL::pointmatcher_support INTERFACE IMPORTED) add_library(CGAL::pointmatcher_support INTERFACE IMPORTED)
set_target_properties(CGAL::pointmatcher_support PROPERTIES target_compile_definitions(CGAL::pointmatcher_support INTERFACE "CGAL_LINKED_WITH_POINTMATCHER")
INTERFACE_COMPILE_DEFINITIONS "CGAL_LINKED_WITH_POINTMATCHER" target_include_directories(CGAL::pointmatcher_support INTERFACE "${libpointmatcher_INCLUDE_DIR}")
INTERFACE_INCLUDE_DIRECTORIES "${libpointmatcher_INCLUDE_DIR}" target_link_libraries(CGAL::pointmatcher_support INTERFACE "${libpointmatcher_LIBRARIES}")
INTERFACE_LINK_LIBRARIES "${libpointmatcher_LIBRARIES}") else()
message(STATUS "NOTICE : the libpointmatcher library requires the following boost components: thread filesystem system program_options date_time chrono.")
endif()
endif() endif()

View File

@ -355,8 +355,10 @@ through the intersection of `l1` and `l2`.
If `l1` and `l2` are parallel, then the bisector is defined as the line If `l1` and `l2` are parallel, then the bisector is defined as the line
which has the same direction as `l1`, and which is at the same distance which has the same direction as `l1`, and which is at the same distance
from `l1` and `l2`. from `l1` and `l2`.
This function requires that `Kernel::RT` supports the `sqrt()` If `Kernel::FT` is not a model of `FieldWithSqrt`
operation. an approximation of the square root will be used in this function,
impacting the exactness of the result even with an (exact) multiprecision
number type.
*/ */
template <typename Kernel> template <typename Kernel>
CGAL::Line_2<Kernel> bisector(const CGAL::Line_2<Kernel> &l1, CGAL::Line_2<Kernel> bisector(const CGAL::Line_2<Kernel> &l1,
@ -379,8 +381,10 @@ passes through the intersection of `h1` and `h2`.
If `h1` and `h2` are parallel, then the bisector is defined as the If `h1` and `h2` are parallel, then the bisector is defined as the
plane which has the same oriented normal vector as `l1`, and which is at plane which has the same oriented normal vector as `l1`, and which is at
the same distance from `h1` and `h2`. the same distance from `h1` and `h2`.
This function requires that `Kernel::RT` supports the `sqrt()` If `Kernel::FT` is not a model of `FieldWithSqrt`
operation. an approximation of the square root will be used in this function,
impacting the exactness of the result even with an (exact) multiprecision
number type.
*/ */
template <typename Kernel> template <typename Kernel>
CGAL::Plane_3<Kernel> bisector(const CGAL::Plane_3<Kernel> &h1, CGAL::Plane_3<Kernel> bisector(const CGAL::Plane_3<Kernel> &h1,

View File

@ -3882,8 +3882,6 @@ public:
If `l1` and `l2` are parallel, then the bisector is defined as the line If `l1` and `l2` are parallel, then the bisector is defined as the line
which has the same direction as `l1`, and which is at the same distance which has the same direction as `l1`, and which is at the same distance
from `l1` and `l2`. from `l1` and `l2`.
This function requires that `Kernel::RT` supports the `sqrt()`
operation.
*/ */
Kernel::Line_2 operator()(const Kernel::Line_2&l1, Kernel::Line_2 operator()(const Kernel::Line_2&l1,
const Kernel::Line_2&l2); const Kernel::Line_2&l2);
@ -3925,8 +3923,6 @@ public:
If `h1` and `h2` are parallel, then the bisector is defined as the If `h1` and `h2` are parallel, then the bisector is defined as the
plane which has the same oriented normal vector as `h1`, and which is at plane which has the same oriented normal vector as `h1`, and which is at
the same distance from `h1` and `h2`. the same distance from `h1` and `h2`.
This function requires that `Kernel::RT` supports the `sqrt()`
operation.
*/ */
Kernel::Plane_3 operator()(const Kernel::Plane_3&h1, Kernel::Plane_3 operator()(const Kernel::Plane_3&h1,
const Kernel::Plane_3&h2); const Kernel::Plane_3&h2);

View File

@ -18,22 +18,9 @@
#ifndef CGAL__TEST_FCT_LINE_2_H #ifndef CGAL__TEST_FCT_LINE_2_H
#define CGAL__TEST_FCT_LINE_2_H #define CGAL__TEST_FCT_LINE_2_H
// Accessory function testing functions that require sqrt().
// Doesn't instantiate anything if RT doesn't support sqrt().
template <class R> template <class R>
bool bool
_test_fct_line_sqrt_2(const R&, CGAL::Tag_false) _test_fct_line_sqrt_2(const R&)
{
// bool UNTESTED_STUFF_BECAUSE_SQRT_IS_NOT_SUPPORTED;
std::cout << std::endl
<< "NOTE : FT doesn't support sqrt(),"
" hence some functions are not tested." << std::endl;
return true;
}
template <class R>
bool
_test_fct_line_sqrt_2(const R&, CGAL::Tag_true)
{ {
typedef typename R::Point_2 Point_2; typedef typename R::Point_2 Point_2;
typedef typename R::Line_2 Line_2; typedef typename R::Line_2 Line_2;
@ -66,7 +53,6 @@ _test_fct_line_2(const R& )
std::cout << "Testing functions Line_2" ; std::cout << "Testing functions Line_2" ;
typedef typename R::RT RT; typedef typename R::RT RT;
typedef typename R::FT FT;
typedef typename R::Point_2 Point_2; typedef typename R::Point_2 Point_2;
typedef typename R::Line_2 Line_2; typedef typename R::Line_2 Line_2;
@ -178,13 +164,9 @@ _test_fct_line_2(const R& )
assert(bl1.oriented_side(p2) == CGAL::ON_POSITIVE_SIDE); assert(bl1.oriented_side(p2) == CGAL::ON_POSITIVE_SIDE);
assert( CGAL::parallel(bl1, bl2) ); assert( CGAL::parallel(bl1, bl2) );
// More tests, that require sqrt(). // More tests, that require sqrt() or use approx.
{ _test_fct_line_sqrt_2(R());
typedef ::CGAL::Algebraic_structure_traits<FT> AST;
static const bool has_sqrt =
! ::boost::is_same< ::CGAL::Null_functor, typename AST::Sqrt >::value;
_test_fct_line_sqrt_2(R(), ::CGAL::Boolean_tag<has_sqrt>());
}
std::cout << "done" << std::endl; std::cout << "done" << std::endl;
return true; return true;
} }

View File

@ -17,22 +17,9 @@
#ifndef CGAL__TEST_FCT_PLANE_3_H #ifndef CGAL__TEST_FCT_PLANE_3_H
#define CGAL__TEST_FCT_PLANE_3_H #define CGAL__TEST_FCT_PLANE_3_H
// Accessory function testing functions that require sqrt().
// Doesn't instantiate anything if RT doesn't support sqrt().
template <class R> template <class R>
bool bool
_test_fct_plane_sqrt_3(const R&, CGAL::Tag_false) _test_fct_plane_sqrt_3(const R&)
{
// bool UNTESTED_STUFF_BECAUSE_SQRT_IS_NOT_SUPPORTED;
std::cout << std::endl
<< "NOTE : FT doesn't support sqrt(),"
" hence some functions are not tested." << std::endl;
return true;
}
template <class R>
bool
_test_fct_plane_sqrt_3(const R&, CGAL::Tag_true)
{ {
typedef typename R::Point_3 Point_3; typedef typename R::Point_3 Point_3;
typedef typename R::Plane_3 Plane_3; typedef typename R::Plane_3 Plane_3;
@ -66,7 +53,6 @@ _test_fct_plane_3(const R& )
std::cout << "Testing functions Plane_3" ; std::cout << "Testing functions Plane_3" ;
typedef typename R::RT RT; typedef typename R::RT RT;
typedef typename R::FT FT;
typedef typename R::Point_3 Point_3; typedef typename R::Point_3 Point_3;
typedef typename R::Plane_3 Plane_3; typedef typename R::Plane_3 Plane_3;
@ -97,11 +83,8 @@ _test_fct_plane_3(const R& )
assert( CGAL::parallel(h1, h2) ); assert( CGAL::parallel(h1, h2) );
assert( ! CGAL::parallel(h1, h5) ); assert( ! CGAL::parallel(h1, h5) );
// More tests, that require sqrt(). // More tests, that require sqrt() or use approx.
typedef ::CGAL::Algebraic_structure_traits<FT> AST; _test_fct_plane_sqrt_3(R());
static const bool has_sqrt =
! ::boost::is_same< ::CGAL::Null_functor, typename AST::Sqrt >::value;
_test_fct_plane_sqrt_3(R(), ::CGAL::Boolean_tag<has_sqrt>());
std::cout << "done" << std::endl; std::cout << "done" << std::endl;
return true; return true;

View File

@ -17,6 +17,7 @@
#include <stack> #include <stack>
#include <typeindex>
#include <CGAL/Surface_mesh/Properties.h> #include <CGAL/Surface_mesh/Properties.h>
@ -933,15 +934,15 @@ public:
/*! /*!
\brief Returns a vector of pairs that describe properties and associated types. \brief Returns a vector of pairs that describe properties and associated types.
*/ */
std::vector<std::pair<std::string, std::type_info> > properties_and_types() const std::vector<std::pair<std::string, std::type_index> > properties_and_types() const
{ {
std::vector<std::string> prop = m_base.properties(); std::vector<std::string> prop = m_base.properties();
prop.erase (prop.begin()); // remove "index" prop.erase (prop.begin()); // remove "index"
prop.erase (prop.begin()); // remove "point" prop.erase (prop.begin()); // remove "point"
std::vector<std::pair<std::string, std::type_info> > out; out.reserve (prop.size()); std::vector<std::pair<std::string, std::type_index> > out; out.reserve (prop.size());
for (std::size_t i = 0; i < prop.size(); ++ i) for (std::size_t i = 0; i < prop.size(); ++ i)
out.push_back (std::make_pair (prop[i], m_base.get_type(prop[i]))); out.push_back (std::make_pair (prop[i], std::type_index(m_base.get_type(prop[i]))));
return out; return out;
} }

View File

@ -106,6 +106,11 @@ int main (int, char**)
point_set.add_property_map<int> ("label", 0); point_set.add_property_map<int> ("label", 0);
point_set.add_property_map<double> ("intensity", 0.0); point_set.add_property_map<double> ("intensity", 0.0);
auto pnt = point_set.properties_and_types();
std::cerr << "Properties = " << std::endl;
for (const auto& p : pnt)
std::cerr << " * " << p.first << " with type " << p.second.name() << std::endl;
test (point_set.base().n_properties() == 4, "point set should have 4 properties."); test (point_set.base().n_properties() == 4, "point set should have 4 properties.");
Point p_before = *(point_set.points().begin()); Point p_before = *(point_set.points().begin());

View File

@ -13,11 +13,8 @@
#define CGAL_ARRAY_H #define CGAL_ARRAY_H
#include <CGAL/config.h> #include <CGAL/config.h>
#ifndef CGAL_CFG_NO_CPP0X_ARRAY #include <array>
# include <array> #include <utility>
#else
# include <boost/array.hpp>
#endif
namespace CGAL { namespace CGAL {
@ -49,7 +46,7 @@ namespace CGAL {
// It's also untrue that this is not documented... It is ! // It's also untrue that this is not documented... It is !
template< typename T, typename... Args > template< typename T, typename... Args >
inline BOOST_CXX14_CONSTEXPR
std::array< T, 1 + sizeof...(Args) > std::array< T, 1 + sizeof...(Args) >
make_array(const T & t, const Args & ... args) make_array(const T & t, const Args & ... args)
{ {
@ -62,12 +59,27 @@ make_array(const T & t, const Args & ... args)
struct Construct_array struct Construct_array
{ {
template <typename T, typename... Args> template <typename T, typename... Args>
std::array<T, 1 + sizeof...(Args)> operator()(const T& t, const Args& ... args) constexpr
std::array<T, 1 + sizeof...(Args)>
operator()(const T& t, const Args& ... args) const
{ {
return make_array (t, args...); return make_array (t, args...);
} }
}; };
template <std::size_t...Is, typename T>
constexpr std::array<T, sizeof...(Is)>
make_filled_array_aux(const T& value, std::index_sequence<Is...>)
{
return {(static_cast<void>(Is), value)...};
}
template <std::size_t N, typename T>
constexpr std::array<T, N> make_filled_array(const T& value)
{
return make_filled_array_aux(value, std::make_index_sequence<N>());
}
} //namespace CGAL } //namespace CGAL
#endif // CGAL_ARRAY_H #endif // CGAL_ARRAY_H

View File

@ -0,0 +1,69 @@
// Copyright (c) 2021 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Laurent Rineau
//
#include <cassert>
namespace CGAL {
namespace Testsuite {
namespace Triangulation_23 {
template <typename Tr>
void test_move_semantic(Tr source_tr) {
const auto dimension = source_tr.dimension();
const auto nb_of_vertices = source_tr.number_of_vertices();
auto check_triangulation_validity = [&](const Tr& tr) {
assert(tr.is_valid());
assert(tr.number_of_vertices() == nb_of_vertices);
assert(tr.dimension() == dimension);
};
auto check_moved_from_triangulation = [](const Tr& tr_copy) {
assert(tr_copy.dimension() == -2);
assert(tr_copy.number_of_vertices() + 1 == 0);
};
auto check_empty_triangulation = [](const Tr& tr_copy2) {
assert(tr_copy2.dimension() == -1);
assert(tr_copy2.number_of_vertices() == 0);
};
// move constructor
{
Tr tr_copy(source_tr);
check_triangulation_validity(tr_copy);
Tr tr_move_constructed(std::move(tr_copy));
check_triangulation_validity(tr_move_constructed);
check_moved_from_triangulation(tr_copy);
Tr tr_copy2(source_tr);
Tr tr_move_constructed2(std::move(tr_copy2));
check_moved_from_triangulation(tr_copy2);
tr_copy2.clear();
check_empty_triangulation(tr_copy2);
Tr tr_copy3(source_tr);
Tr tr_move_constructed3(std::move(tr_copy3));
check_moved_from_triangulation(tr_copy3);
tr_copy3 = source_tr;
check_triangulation_validity(tr_copy3);
}
// move-assignment
{
Tr tr_copy4(source_tr);
Tr tr_move_assigned;
tr_move_assigned = std::move(tr_copy4);
check_triangulation_validity(tr_move_assigned);
check_moved_from_triangulation(tr_copy4);
}
};
}
}
}

View File

@ -37,6 +37,7 @@
#include <map> #include <map>
#include <vector> #include <vector>
#include <array> #include <array>
#include <CGAL/array.h>
namespace CGAL { namespace CGAL {
@ -82,7 +83,14 @@ public:
#endif #endif
private: private:
void init_hierarchy() {
hierarchy[0] = this;
for(int i=1; i<Triangulation_hierarchy_2__maxlevel; ++i)
hierarchy[i] = &hierarchy_triangulations[i-1];
}
// here is the stack of triangulations which form the hierarchy // here is the stack of triangulations which form the hierarchy
std::array<Tr_Base,Triangulation_hierarchy_2__maxlevel-1> hierarchy_triangulations;
std::array<Tr_Base*,Triangulation_hierarchy_2__maxlevel> hierarchy; std::array<Tr_Base*,Triangulation_hierarchy_2__maxlevel> hierarchy;
boost::rand48 random; boost::rand48 random;
@ -93,13 +101,10 @@ public:
Triangulation_hierarchy_2(Triangulation_hierarchy_2&& other) Triangulation_hierarchy_2(Triangulation_hierarchy_2&& other)
noexcept( noexcept(Tr_Base(std::move(other))) ) noexcept( noexcept(Tr_Base(std::move(other))) )
: Tr_Base(std::move(other)) : Tr_Base(std::move(other))
, hierarchy_triangulations(std::move(other.hierarchy_triangulations))
, random(std::move(other.random)) , random(std::move(other.random))
{ {
hierarchy[0] = this; init_hierarchy();
for(int i=1; i<Triangulation_hierarchy_2__maxlevel; ++i) {
hierarchy[i] = other.hierarchy[i];
other.hierarchy[i] = nullptr;
}
} }
template<class InputIterator> template<class InputIterator>
@ -107,10 +112,7 @@ public:
const Geom_traits& traits = Geom_traits()) const Geom_traits& traits = Geom_traits())
: Tr_Base(traits) : Tr_Base(traits)
{ {
hierarchy[0] = this; init_hierarchy();
for(int i=1;i<Triangulation_hierarchy_2__maxlevel;++i)
hierarchy[i] = new Tr_Base(traits);
insert (first, beyond); insert (first, beyond);
} }
@ -120,15 +122,11 @@ public:
noexcept( noexcept(Triangulation_hierarchy_2(std::move(other))) ) noexcept( noexcept(Triangulation_hierarchy_2(std::move(other))) )
{ {
static_cast<Tr_Base&>(*this) = std::move(other); static_cast<Tr_Base&>(*this) = std::move(other);
hierarchy[0] = this; hierarchy_triangulations = std::move(other.hierarchy_triangulations);
for(int i=1; i<Triangulation_hierarchy_2__maxlevel; ++i) {
hierarchy[i] = other.hierarchy[i];
other.hierarchy[i] = nullptr;
}
return *this; return *this;
} }
~Triangulation_hierarchy_2(); ~Triangulation_hierarchy_2() = default;
//Helping //Helping
void copy_triangulation(const Triangulation_hierarchy_2 &tr); void copy_triangulation(const Triangulation_hierarchy_2 &tr);
@ -293,10 +291,11 @@ template <class Tr_>
Triangulation_hierarchy_2<Tr_>:: Triangulation_hierarchy_2<Tr_>::
Triangulation_hierarchy_2(const Geom_traits& traits) Triangulation_hierarchy_2(const Geom_traits& traits)
: Tr_Base(traits) : Tr_Base(traits)
, hierarchy_triangulations(
make_filled_array<Triangulation_hierarchy_2__maxlevel-1,
Tr_Base>(traits))
{ {
hierarchy[0] = this; init_hierarchy();
for(int i=1;i<Triangulation_hierarchy_2__maxlevel;++i)
hierarchy[i] = new Tr_Base(traits);
} }
@ -304,12 +303,8 @@ Triangulation_hierarchy_2(const Geom_traits& traits)
template <class Tr_> template <class Tr_>
Triangulation_hierarchy_2<Tr_>:: Triangulation_hierarchy_2<Tr_>::
Triangulation_hierarchy_2(const Triangulation_hierarchy_2<Tr_> &tr) Triangulation_hierarchy_2(const Triangulation_hierarchy_2<Tr_> &tr)
: Tr_Base() : Triangulation_hierarchy_2(tr.geom_traits())
{ {
// create an empty triangulation to be able to delete it !
hierarchy[0] = this;
for(int i=1;i<Triangulation_hierarchy_2__maxlevel;++i)
hierarchy[i] = new Tr_Base(tr.geom_traits());
copy_triangulation(tr); copy_triangulation(tr);
} }
@ -392,23 +387,9 @@ void
Triangulation_hierarchy_2<Tr_>:: Triangulation_hierarchy_2<Tr_>::
swap(Triangulation_hierarchy_2<Tr_> &tr) swap(Triangulation_hierarchy_2<Tr_> &tr)
{ {
Tr_Base* temp;
Tr_Base::swap(tr); Tr_Base::swap(tr);
for(int i= 1; i<Triangulation_hierarchy_2__maxlevel; ++i){ using std::swap;
temp = hierarchy[i]; swap(hierarchy_triangulations, tr.hierarchy_triangulations);
hierarchy[i] = tr.hierarchy[i];
tr.hierarchy[i]= temp;
}
}
template <class Tr_>
Triangulation_hierarchy_2<Tr_>::
~Triangulation_hierarchy_2()
{
clear();
for(int i= 1; i<Triangulation_hierarchy_2__maxlevel; ++i){
delete hierarchy[i];
}
} }
template <class Tr_> template <class Tr_>

View File

@ -31,6 +31,7 @@
#include <CGAL/_test_fct_is_infinite.h> #include <CGAL/_test_fct_is_infinite.h>
#include <CGAL/_test_triangulation_iterators.h> #include <CGAL/_test_triangulation_iterators.h>
#include <CGAL/_test_triangulation_circulators.h> #include <CGAL/_test_triangulation_circulators.h>
#include <CGAL/Testsuite/Triangulation_23/test_move_semantic.h>
template <class Triangul> template <class Triangul>
@ -281,6 +282,15 @@ _test_cls_triangulation_short_2( const Triangul &)
assert( T2_3_4.number_of_vertices() == 11 ); assert( T2_3_4.number_of_vertices() == 11 );
assert( T2_3_4.is_valid() ); assert( T2_3_4.is_valid() );
/****************************/
/******* MOVE SEMANTIC*******/
std::cout << " move constructors and move assignment" << std::endl;
namespace test_tr_23 = CGAL::Testsuite::Triangulation_23;
test_tr_23::test_move_semantic(T0_1);
test_tr_23::test_move_semantic(T1_5);
test_tr_23::test_move_semantic(T2_8);
test_tr_23::test_move_semantic(T2_3);
/*********************************************/ /*********************************************/
/****** FINITE/INFINITE VERTICES/FACES *******/ /****** FINITE/INFINITE VERTICES/FACES *******/

View File

@ -51,6 +51,7 @@
#include <boost/mpl/if.hpp> #include <boost/mpl/if.hpp>
#include <array> #include <array>
#include <CGAL/array.h>
#endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO #endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO
@ -92,7 +93,14 @@ public:
private: private:
void init_hierarchy() {
hierarchy[0] = this;
for(int i=1; i<maxlevel; ++i)
hierarchy[i] = &hierarchy_triangulations[i-1];
}
// here is the stack of triangulations which form the hierarchy // here is the stack of triangulations which form the hierarchy
std::array<Tr_Base,maxlevel-1> hierarchy_triangulations;
std::array<Tr_Base*,maxlevel> hierarchy; std::array<Tr_Base*,maxlevel> hierarchy;
boost::rand48 random; boost::rand48 random;
@ -111,23 +119,19 @@ public:
Triangulation_hierarchy_3(Triangulation_hierarchy_3&& other) Triangulation_hierarchy_3(Triangulation_hierarchy_3&& other)
noexcept( noexcept(Tr_Base(std::move(other))) ) noexcept( noexcept(Tr_Base(std::move(other))) )
: Tr_Base(std::move(other)) : Tr_Base(std::move(other))
, hierarchy_triangulations(std::move(other.hierarchy_triangulations))
, random(std::move(other.random)) , random(std::move(other.random))
{ {
hierarchy[0] = this; init_hierarchy();
for(int i=1; i<maxlevel; ++i) {
hierarchy[i] = other.hierarchy[i];
other.hierarchy[i] = nullptr;
}
} }
template < typename InputIterator > template < typename InputIterator >
Triangulation_hierarchy_3(InputIterator first, InputIterator last, Triangulation_hierarchy_3(InputIterator first, InputIterator last,
const Geom_traits& traits = Geom_traits()) const Geom_traits& traits = Geom_traits())
: Tr_Base(traits) : Tr_Base(traits)
, hierarchy_triangulations(make_filled_array<maxlevel-1, Tr_Base>(traits))
{ {
hierarchy[0] = this; init_hierarchy();
for(int i=1; i<maxlevel; ++i)
hierarchy[i] = new Tr_Base(traits);
insert(first, last); insert(first, last);
} }
@ -142,27 +146,17 @@ public:
noexcept( noexcept(Triangulation_hierarchy_3(std::move(other))) ) noexcept( noexcept(Triangulation_hierarchy_3(std::move(other))) )
{ {
static_cast<Tr_Base&>(*this) = std::move(other); static_cast<Tr_Base&>(*this) = std::move(other);
hierarchy[0] = this; hierarchy_triangulations = std::move(other.hierarchy_triangulations);
for(int i=1; i<maxlevel; ++i) {
hierarchy[i] = other.hierarchy[i];
other.hierarchy[i] = nullptr;
}
return *this; return *this;
} }
~Triangulation_hierarchy_3() ~Triangulation_hierarchy_3() = default;
{
clear();
for(int i=1; i<maxlevel; ++i) {
delete hierarchy[i];
}
};
void swap(Triangulation_hierarchy_3 &tr) void swap(Triangulation_hierarchy_3 &tr)
{ {
Tr_Base::swap(tr); Tr_Base::swap(tr);
for(int i=1; i<maxlevel; ++i) using std::swap;
std::swap(hierarchy[i], tr.hierarchy[i]); swap(hierarchy_triangulations, tr.hierarchy_triangulations);
}; };
void clear(); void clear();
@ -460,10 +454,9 @@ template <class Tr >
Triangulation_hierarchy_3<Tr>:: Triangulation_hierarchy_3<Tr>::
Triangulation_hierarchy_3(const Geom_traits& traits) Triangulation_hierarchy_3(const Geom_traits& traits)
: Tr_Base(traits) : Tr_Base(traits)
, hierarchy_triangulations(make_filled_array<maxlevel-1, Tr_Base>(traits))
{ {
hierarchy[0] = this; init_hierarchy();
for(int i=1;i<maxlevel;++i)
hierarchy[i] = new Tr_Base(traits);
} }
// copy constructor duplicates vertices and cells // copy constructor duplicates vertices and cells
@ -471,10 +464,9 @@ template <class Tr>
Triangulation_hierarchy_3<Tr>:: Triangulation_hierarchy_3<Tr>::
Triangulation_hierarchy_3(const Triangulation_hierarchy_3<Tr> &tr) Triangulation_hierarchy_3(const Triangulation_hierarchy_3<Tr> &tr)
: Tr_Base(tr) : Tr_Base(tr)
, hierarchy_triangulations(tr.hierarchy_triangulations)
{ {
hierarchy[0] = this; init_hierarchy();
for(int i=1; i<maxlevel; ++i)
hierarchy[i] = new Tr_Base(*tr.hierarchy[i]);
// up and down have been copied in straightforward way // up and down have been copied in straightforward way
// compute a map at lower level // compute a map at lower level

View File

@ -31,6 +31,7 @@
#include <CGAL/Random.h> #include <CGAL/Random.h>
#include <CGAL/Testsuite/use.h> #include <CGAL/Testsuite/use.h>
#include <CGAL/internal/Has_nested_type_Bare_point.h> #include <CGAL/internal/Has_nested_type_Bare_point.h>
#include <CGAL/Testsuite/Triangulation_23/test_move_semantic.h>
// Accessory set of functions to differentiate between // Accessory set of functions to differentiate between
// Delaunay::nearest_vertex[_in_cell] and // Delaunay::nearest_vertex[_in_cell] and
@ -421,7 +422,8 @@ _test_cls_delaunay_3(const Triangulation &)
assert(T1.number_of_vertices() == 0); assert(T1.number_of_vertices() == 0);
assert(T1.is_valid()); assert(T1.is_valid());
namespace test_tr_23 = CGAL::Testsuite::Triangulation_23;
test_tr_23::test_move_semantic(T0);
// Affectation : // Affectation :
T1=T0; T1=T0;
@ -454,6 +456,7 @@ _test_cls_delaunay_3(const Triangulation &)
assert(T1_0.dimension()==1); assert(T1_0.dimension()==1);
assert(T1_0.number_of_vertices()==n); assert(T1_0.number_of_vertices()==n);
assert(T1_0.is_valid()); assert(T1_0.is_valid());
test_tr_23::test_move_semantic(T1_0);
std::cout << " Constructor7 " << std::endl; std::cout << " Constructor7 " << std::endl;
Cls T1_1; Cls T1_1;
n = T1_1.insert(l2.begin(),l2.end()); n = T1_1.insert(l2.begin(),l2.end());
@ -514,6 +517,8 @@ _test_cls_delaunay_3(const Triangulation &)
assert(T2_0.dimension()==2); assert(T2_0.dimension()==2);
assert(T2_0.number_of_vertices()==8); assert(T2_0.number_of_vertices()==8);
test_tr_23::test_move_semantic(T2_0);
{ {
Cls Tfromfile; Cls Tfromfile;
std::cout << " I/O" << std::endl; std::cout << " I/O" << std::endl;
@ -562,6 +567,8 @@ _test_cls_delaunay_3(const Triangulation &)
assert(T3_0.number_of_vertices()==125); assert(T3_0.number_of_vertices()==125);
assert(T3_0.dimension()==3); assert(T3_0.dimension()==3);
test_tr_23::test_move_semantic(T3_0);
if (del) { if (del) {
std::cout << " deletion in Delaunay - grid case - (dim 3) " << std::cout << " deletion in Delaunay - grid case - (dim 3) " <<
std::endl; std::endl;
@ -1194,6 +1201,19 @@ _test_cls_delaunay_3(const Triangulation &)
_test_remove_cluster<Triangulation>(); _test_remove_cluster<Triangulation>();
} }
// Test from issue https://github.com/CGAL/cgal/issues/5396
{
auto Triangulate = []() -> Triangulation
{
Triangulation tri;
for (int i=0; i<10; i++)
tri.insert(Point(i+1, i+2, i+3));
return tri;
};
auto t = Triangulate();
auto t2 = std::move(t);
}
} }
#endif // CGAL_TEST_CLS_DELAUNAY_C #endif // CGAL_TEST_CLS_DELAUNAY_C

View File

@ -17,6 +17,8 @@
#include <list> #include <list>
#include <type_traits> #include <type_traits>
#include <CGAL/use.h> #include <CGAL/use.h>
#include <CGAL/Testsuite/Triangulation_23/test_move_semantic.h>
template <class Triangulation> template <class Triangulation>
void void
_test_cls_regular_3(const Triangulation &) _test_cls_regular_3(const Triangulation &)
@ -205,6 +207,7 @@ _test_cls_regular_3(const Triangulation &)
<< T.number_of_vertices() << std::endl; << T.number_of_vertices() << std::endl;
assert(T.is_valid()); assert(T.is_valid());
assert(T.dimension()==3); assert(T.dimension()==3);
namespace test_tr_23 = CGAL::Testsuite::Triangulation_23;
test_tr_23::test_move_semantic(T);
} }

View File

@ -23,6 +23,7 @@
#include <CGAL/Random.h> #include <CGAL/Random.h>
#include <CGAL/Testsuite/use.h> #include <CGAL/Testsuite/use.h>
#include <CGAL/use.h> #include <CGAL/use.h>
#include <CGAL/Testsuite/Triangulation_23/test_move_semantic.h>
template <class Triangulation, class Container> template <class Triangulation, class Container>
bool check_all_are_finite(Triangulation* tr, const Container& cont) bool check_all_are_finite(Triangulation* tr, const Container& cont)
@ -286,7 +287,8 @@ _test_cls_triangulation_3(const Triangulation &)
assert(T1.number_of_vertices() == 0); assert(T1.number_of_vertices() == 0);
assert(T1.is_valid()); assert(T1.is_valid());
namespace test_tr_23 = CGAL::Testsuite::Triangulation_23;
test_tr_23::test_move_semantic(T0);
// Assignment // Assignment
T1=T0; T1=T0;
@ -363,12 +365,14 @@ _test_cls_triangulation_3(const Triangulation &)
assert(T2_0.dimension()==1); assert(T2_0.dimension()==1);
assert(T2_0.number_of_vertices()==3); assert(T2_0.number_of_vertices()==3);
test_tr_23::test_move_semantic(T2_0);
v0=T2_0.insert(p4); v0=T2_0.insert(p4);
assert(T2_0.is_valid()); assert(T2_0.is_valid());
assert(T2_0.dimension()==2); assert(T2_0.dimension()==2);
assert(T2_0.number_of_vertices()==4); assert(T2_0.number_of_vertices()==4);
test_tr_23::test_move_semantic(T2_0);
v0=T2_0.insert(p5); v0=T2_0.insert(p5);
v0=T2_0.insert(p6); v0=T2_0.insert(p6);
@ -380,6 +384,8 @@ _test_cls_triangulation_3(const Triangulation &)
assert(T2_0.dimension()==2); assert(T2_0.dimension()==2);
assert(T2_0.number_of_vertices()==8); assert(T2_0.number_of_vertices()==8);
test_tr_23::test_move_semantic(T2_0);
if (! del) // to avoid doing the following tests for both Delaunay if (! del) // to avoid doing the following tests for both Delaunay
// and non Delaunay triangulations // and non Delaunay triangulations
{ {
@ -403,6 +409,8 @@ _test_cls_triangulation_3(const Triangulation &)
assert( T2_1.dimension()==2 ); assert( T2_1.dimension()==2 );
assert( T2_1.is_valid() ); assert( T2_1.is_valid() );
test_tr_23::test_move_semantic(T2_1);
std::cout << " Constructor11 " << std::endl; std::cout << " Constructor11 " << std::endl;
// 3-dimensional triangulations // 3-dimensional triangulations
// This is a simple grid : // This is a simple grid :