diff --git a/.travis.yml b/.travis.yml index c176918d6d2..398df77da8b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -53,7 +53,7 @@ env: compiler: clang-3.6 install: - echo "$PWD" - - if [ -n "$TRAVIS_PULL_REQUEST" ] && [ "$PACKAGE" != CHECK ]; then DO_IGNORE=FALSE; for ARG in $(echo "$PACKAGE");do . $PWD/.travis/test_package.sh "$PWD" "$ARG"; echo "DO_IGNORE is $DO_IGNORE"; if [ "$DO_IGNORE" = "TRUE" ]; then travis_terminate 0; fi; done;fi + - if [ -n "$TRAVIS_PULL_REQUEST" ] && [ "$PACKAGE" != CHECK ]; then DO_IGNORE=FALSE; for ARG in $(echo "$PACKAGE");do if [ "$ARG" = "Maintenance" ]; then continue; fi; . $PWD/.travis/test_package.sh "$PWD" "$ARG"; echo "DO_IGNORE is $DO_IGNORE"; if [ "$DO_IGNORE" = "FALSE" ]; then break; fi; done; if [ "$DO_IGNORE" = "TRUE" ]; then travis_terminate 0; fi;fi - bash .travis/install.sh - export CXX=clang++-3.6 CC=clang-3.6; before_script: @@ -68,7 +68,7 @@ before_script: - cd .. script: - cd ./.travis -- bash -x -e ./build_package.sh $PACKAGE +- bash ./build_package.sh $PACKAGE notifications: email: on_success: change # default: always diff --git a/.travis/build_package.sh b/.travis/build_package.sh index a211a18ab5b..f1faf434ddd 100755 --- a/.travis/build_package.sh +++ b/.travis/build_package.sh @@ -1,5 +1,6 @@ #!/bin/bash set -e +[ -n "$CGAL_DEBUG_TRAVIS" ] && set -x CXX_FLAGS="-DCGAL_NDEBUG" @@ -53,6 +54,10 @@ ROOT="$PWD/.." NEED_3D=0 for ARG in $(echo "$@") do +#skip package maintenance + if [ "$ARG" = "Maintenance" ]; then + continue + fi cd $ROOT #install openmesh only if necessary if [ "$ARG" = "CHECK" ] || [ "$ARG" = BGL ] || [ "$ARG" = Convex_hull_3 ] ||\ @@ -72,7 +77,8 @@ cd $ROOT zsh $ROOT/Scripts/developer_scripts/test_merge_of_branch HEAD #test dependencies cd $ROOT - bash Scripts/developer_scripts/cgal_check_dependencies.sh /usr/bin/doxygen + bash Scripts/developer_scripts/cgal_check_dependencies.sh --check_headers /usr/bin/doxygen + cd .travis #parse current matrix and check that no package has been forgotten diff --git a/.travis/install.sh b/.travis/install.sh index ee9f7047d7d..4d78446fc74 100644 --- a/.travis/install.sh +++ b/.travis/install.sh @@ -1,6 +1,6 @@ #!/bin/bash -set -x +[ -n "$CGAL_DEBUG_TRAVIS" ] && set -x DONE=0 while [ $DONE = 0 ] do diff --git a/.travis/template.txt b/.travis/template.txt index 6bcf144ba17..c023fe68f3e 100644 --- a/.travis/template.txt +++ b/.travis/template.txt @@ -10,7 +10,7 @@ env: compiler: clang-3.6 install: - echo "$PWD" - - if [ -n "$TRAVIS_PULL_REQUEST" ] && [ "$PACKAGE" != CHECK ]; then DO_IGNORE=FALSE; for ARG in $(echo "$PACKAGE");do . $PWD/.travis/test_package.sh "$PWD" "$ARG"; echo "DO_IGNORE is $DO_IGNORE"; if [ "$DO_IGNORE" = "TRUE" ]; then travis_terminate 0; fi; done;fi + - if [ -n "$TRAVIS_PULL_REQUEST" ] && [ "$PACKAGE" != CHECK ]; then DO_IGNORE=FALSE; for ARG in $(echo "$PACKAGE");do if [ "$ARG" = "Maintenance" ]; then continue; fi; . $PWD/.travis/test_package.sh "$PWD" "$ARG"; echo "DO_IGNORE is $DO_IGNORE"; if [ "$DO_IGNORE" = "FALSE" ]; then break; fi; done; if [ "$DO_IGNORE" = "TRUE" ]; then travis_terminate 0; fi;fi - bash .travis/install.sh - export CXX=clang++-3.6 CC=clang-3.6; before_script: @@ -25,7 +25,7 @@ before_script: - cd .. script: - cd ./.travis -- bash -x -e ./build_package.sh $PACKAGE +- bash ./build_package.sh $PACKAGE notifications: email: on_success: change # default: always diff --git a/AABB_tree/demo/AABB_tree/CMakeLists.txt b/AABB_tree/demo/AABB_tree/CMakeLists.txt index 77b7c395440..67d82685b54 100644 --- a/AABB_tree/demo/AABB_tree/CMakeLists.txt +++ b/AABB_tree/demo/AABB_tree/CMakeLists.txt @@ -27,14 +27,8 @@ find_package(Qt5 QUIET COMPONENTS Xml Script OpenGL Gui Svg) include( ${CGAL_USE_FILE} ) -# Find QGLViewer -if(Qt5_FOUND) - find_package(QGLViewer) -endif(Qt5_FOUND) -if(CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND) - - include_directories ( ${QGLVIEWER_INCLUDE_DIR} ) +if(CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND) qt5_wrap_ui( UI_FILES MainWindow.ui ) @@ -55,20 +49,22 @@ if(CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND) "${CMAKE_CURRENT_BINARY_DIR}/Viewer_moc.cpp" "${CMAKE_CURRENT_BINARY_DIR}/Scene_moc.cpp" ) - add_executable ( AABB_demo AABB_demo.cpp ${UI_FILES} ${CGAL_Qt5_RESOURCE_FILES} ${CGAL_Qt5_MOC_FILES}) + add_executable ( AABB_demo AABB_demo.cpp ${UI_FILES} ${CGAL_Qt5_RESOURCE_FILES} + #${CGAL_Qt5_MOC_FILES} + ) # Link with Qt libraries target_link_libraries( AABB_demo PRIVATE - Qt5::OpenGL Qt5::Gui + Qt5::OpenGL Qt5::Gui Qt5::Xml CGAL::CGAL CGAL::CGAL_Qt5 - ${QGLVIEWER_LIBRARIES}) + ) add_to_cached_list( CGAL_EXECUTABLE_TARGETS AABB_demo ) include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake) cgal_add_compilation_test(AABB_demo) -else (CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND) +else (CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND) set(AABB_MISSING_DEPS "") @@ -84,10 +80,6 @@ else (CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND) set(AABB_MISSING_DEPS "Qt5, ${AABB_MISSING_DEPS}") endif() - if(NOT QGLVIEWER_FOUND) - set(AABB_MISSING_DEPS "QGLViewer, ${AABB_MISSING_DEPS}") - endif() - message(STATUS "NOTICE: This demo requires ${AABB_MISSING_DEPS}and will not be compiled.") -endif (CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND) +endif (CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND ) diff --git a/AABB_tree/demo/AABB_tree/MainWindow.cpp b/AABB_tree/demo/AABB_tree/MainWindow.cpp index 57377068fec..8cd596d6bbc 100644 --- a/AABB_tree/demo/AABB_tree/MainWindow.cpp +++ b/AABB_tree/demo/AABB_tree/MainWindow.cpp @@ -76,7 +76,7 @@ void MainWindow::updateViewerBBox() const double xmax = bbox.xmax(); const double ymax = bbox.ymax(); const double zmax = bbox.zmax(); - qglviewer::Vec + CGAL::qglviewer::Vec vec_min(xmin, ymin, zmin), vec_max(xmax, ymax, zmax); m_pViewer->setSceneBoundingBox(vec_min,vec_max); @@ -411,27 +411,18 @@ void MainWindow::on_actionRefine_loop_triggered() void MainWindow::on_actionSave_snapshot_triggered() { - // save snapshot to file - QApplication::setOverrideCursor(Qt::WaitCursor); - QString filename = QFileDialog::getSaveFileName(this,tr("Save snapshot to file..."),"snapshot00.png","*.png"); - m_pViewer->saveSnapshot(filename); - QApplication::restoreOverrideCursor(); + return; } void MainWindow::on_actionCopy_snapshot_triggered() { // copy snapshot to clipboard - QApplication::setOverrideCursor(Qt::WaitCursor); + QApplication::setOverrideCursor(Qt::WaitCursor); QClipboard *qb = QApplication::clipboard(); m_pViewer->makeCurrent(); m_pViewer->raise(); -#if QGLVIEWER_VERSION >= 0x020700 QImage snapshot = m_pViewer->grabFramebuffer(); -#else - QImage snapshot = m_pViewer->grabFrameBuffer(true); - -#endif qb->setImage(snapshot); - QApplication::restoreOverrideCursor(); + QApplication::restoreOverrideCursor(); } diff --git a/AABB_tree/demo/AABB_tree/Refiner.h b/AABB_tree/demo/AABB_tree/Refiner.h index 74d9f86aa79..f03c0ef4216 100644 --- a/AABB_tree/demo/AABB_tree/Refiner.h +++ b/AABB_tree/demo/AABB_tree/Refiner.h @@ -68,7 +68,7 @@ class Refiner typedef typename Polyhedron::Edge_iterator Edge_iterator; typedef std::priority_queue, - less > PQueue; + ::less > PQueue; // data PQueue m_queue; Polyhedron* m_pMesh; diff --git a/AABB_tree/demo/AABB_tree/Scene.cpp b/AABB_tree/demo/AABB_tree/Scene.cpp index 09277853f80..ef0e42e9e0a 100644 --- a/AABB_tree/demo/AABB_tree/Scene.cpp +++ b/AABB_tree/demo/AABB_tree/Scene.cpp @@ -490,7 +490,7 @@ void Scene::compute_texture(int i, int j,Color_ramp pos_ramp ,Color_ramp neg_ram } -void Scene::attrib_buffers(QGLViewer* viewer) +void Scene::attrib_buffers(CGAL::QGLViewer* viewer) { QMatrix4x4 mvpMatrix; double mat[16]; @@ -589,7 +589,7 @@ void Scene::update_bbox() << " facets)" << std::endl; } -void Scene::draw(QGLViewer* viewer) +void Scene::draw(CGAL::QGLViewer* viewer) { if(!gl_init) initGL(); @@ -766,8 +766,8 @@ Plane Scene::random_plane(const CGAL::Bbox_3& bbox) Plane Scene::frame_plane() const { - const qglviewer::Vec& pos = m_frame->position(); - const qglviewer::Vec& n = m_frame->inverseTransformOf(qglviewer::Vec(0.f, 0.f, 1.f)); + const CGAL::qglviewer::Vec& pos = m_frame->position(); + const CGAL::qglviewer::Vec& n = m_frame->inverseTransformOf(CGAL::qglviewer::Vec(0.f, 0.f, 1.f)); return Plane(n[0], n[1], n[2], - n * pos); } diff --git a/AABB_tree/demo/AABB_tree/Scene.h b/AABB_tree/demo/AABB_tree/Scene.h index 5ee0948cf1c..8bf07460af2 100644 --- a/AABB_tree/demo/AABB_tree/Scene.h +++ b/AABB_tree/demo/AABB_tree/Scene.h @@ -17,9 +17,8 @@ #include #include -#include -#include -#include +#include +#include #include #include #include @@ -71,7 +70,7 @@ private: typedef CGAL::AABB_traits Edge_Traits; typedef CGAL::AABB_tree Edge_tree; - typedef qglviewer::ManipulatedFrame ManipulatedFrame; + typedef CGAL::qglviewer::ManipulatedFrame ManipulatedFrame; enum Cut_planes_types { NONE, UNSIGNED_FACETS, SIGNED_FACETS, UNSIGNED_EDGES, CUT_SEGMENTS @@ -79,7 +78,7 @@ private: public: QGLContext* context; - void draw(QGLViewer*); + void draw(CGAL::QGLViewer*); void update_bbox(); Bbox bbox() { return m_bbox; } ManipulatedFrame* manipulatedFrame() const { return m_frame; } @@ -171,7 +170,7 @@ private: QOpenGLShaderProgram rendering_program; void initialize_buffers(); void compute_elements(int mode); - void attrib_buffers(QGLViewer*); + void attrib_buffers(CGAL::QGLViewer*); void compile_shaders(); void compute_texture(int, int, Color_ramp, Color_ramp); diff --git a/AABB_tree/demo/AABB_tree/Viewer.cpp b/AABB_tree/demo/AABB_tree/Viewer.cpp index 56de4c959eb..a1d01723581 100644 --- a/AABB_tree/demo/AABB_tree/Viewer.cpp +++ b/AABB_tree/demo/AABB_tree/Viewer.cpp @@ -5,7 +5,7 @@ #include Viewer::Viewer(QWidget* parent) - : QGLViewer(CGAL::Qt::createOpenGLContext(),parent), + : CGAL::QGLViewer(parent), m_pScene(NULL), m_custom_mouse(false) { @@ -18,7 +18,7 @@ void Viewer::setScene(Scene* pScene) void Viewer::draw() { - QGLViewer::draw(); + CGAL::QGLViewer::draw(); if(m_pScene != NULL) { m_pScene->draw(this); @@ -28,7 +28,7 @@ void Viewer::draw() void Viewer::initializeGL() { - QGLViewer::initializeGL(); + CGAL::QGLViewer::initializeGL(); setBackgroundColor(::Qt::white); //m_pScene->initGL(this); } @@ -43,7 +43,7 @@ void Viewer::mousePressEvent(QMouseEvent* e) m_custom_mouse = true; } - QGLViewer::mousePressEvent(e); + CGAL::QGLViewer::mousePressEvent(e); } void Viewer::mouseReleaseEvent(QMouseEvent* e) @@ -59,6 +59,6 @@ void Viewer::mouseReleaseEvent(QMouseEvent* e) m_custom_mouse = false; } - QGLViewer::mouseReleaseEvent(e); + CGAL::QGLViewer::mouseReleaseEvent(e); } diff --git a/AABB_tree/demo/AABB_tree/Viewer.h b/AABB_tree/demo/AABB_tree/Viewer.h index 7e99e5c9e84..696dd0f0ddd 100644 --- a/AABB_tree/demo/AABB_tree/Viewer.h +++ b/AABB_tree/demo/AABB_tree/Viewer.h @@ -1,20 +1,20 @@ #ifndef VIEWER_H #define VIEWER_H #include -#include +#include // forward declarations class QWidget; class Scene; -class Viewer : public QGLViewer{ +class Viewer : public CGAL::QGLViewer{ Q_OBJECT public: Viewer(QWidget * parent); - // overload several QGLViewer virtual functions + // overload several CGAL::QGLViewer virtual functions void draw(); void initializeGL(); void setScene(Scene* pScene); diff --git a/AABB_tree/doc/AABB_tree/Concepts/AABBGeomTraits.h b/AABB_tree/doc/AABB_tree/Concepts/AABBGeomTraits.h index a579453e9f2..ec017f1efe3 100644 --- a/AABB_tree/doc/AABB_tree/Concepts/AABBGeomTraits.h +++ b/AABB_tree/doc/AABB_tree/Concepts/AABBGeomTraits.h @@ -66,7 +66,8 @@ typedef unspecified_type Construct_sphere_3; /*! A functor object to compute the point on a geometric primitive which is closest from a query. Provides the operator: -`Point_3 operator()(const Type_2& type_2, const Point_3& p);` where `Type_2` is any type among `Segment_3` and `Triangle_3`. The operator returns the point on `type_2` which is closest to `p`. +`Point_3 operator()(const Type_2& type_2, const Point_3& p);` where `Type_2` can be any of the following types : `Segment_3`, `Ray_3`, or `Triangle_3`. +The operator returns the point on `type_2` which is closest to `p`. */ typedef unspecified_type Construct_projected_point_3; diff --git a/AABB_tree/include/CGAL/AABB_traits.h b/AABB_tree/include/CGAL/AABB_traits.h index da2fd2da756..632f2256d4b 100644 --- a/AABB_tree/include/CGAL/AABB_traits.h +++ b/AABB_tree/include/CGAL/AABB_traits.h @@ -291,7 +291,8 @@ public: */ class Sort_primitives { - const AABB_traits& m_traits; + typedef AABB_traits Traits; + const Traits& m_traits; public: Sort_primitives(const AABB_traits& traits) : m_traits(traits) {} @@ -302,16 +303,16 @@ public: const typename AT::Bounding_box& bbox) const { PrimitiveIterator middle = first + (beyond - first)/2; - switch(longest_axis(bbox)) + switch(Traits::longest_axis(bbox)) { case AT::CGAL_AXIS_X: // sort along x - std::nth_element(first, middle, beyond, boost::bind(less_x,_1,_2,m_traits)); + std::nth_element(first, middle, beyond, boost::bind(Traits::less_x,_1,_2,m_traits)); break; case AT::CGAL_AXIS_Y: // sort along y - std::nth_element(first, middle, beyond, boost::bind(less_y,_1,_2,m_traits)); + std::nth_element(first, middle, beyond, boost::bind(Traits::less_y,_1,_2,m_traits)); break; case AT::CGAL_AXIS_Z: // sort along z - std::nth_element(first, middle, beyond, boost::bind(less_z,_1,_2,m_traits)); + std::nth_element(first, middle, beyond, boost::bind(Traits::less_z,_1,_2,m_traits)); break; default: CGAL_error(); diff --git a/AABB_tree/test/AABB_tree/AABB_test_util.h b/AABB_tree/test/AABB_tree/AABB_test_util.h index 55eeb4d84c8..bd5443a8548 100644 --- a/AABB_tree/test/AABB_tree/AABB_test_util.h +++ b/AABB_tree/test/AABB_tree/AABB_test_util.h @@ -29,7 +29,7 @@ #include #include -#include +#include #include diff --git a/AABB_tree/test/AABB_tree/aabb_any_all_benchmark.cpp b/AABB_tree/test/AABB_tree/aabb_any_all_benchmark.cpp index 70626442ac3..394bce109b5 100644 --- a/AABB_tree/test/AABB_tree/aabb_any_all_benchmark.cpp +++ b/AABB_tree/test/AABB_tree/aabb_any_all_benchmark.cpp @@ -15,7 +15,6 @@ #include #include -#include #include diff --git a/AABB_tree/test/AABB_tree/aabb_correctness_triangle_test.cpp b/AABB_tree/test/AABB_tree/aabb_correctness_triangle_test.cpp index 556a6f81bdd..8d511bea090 100644 --- a/AABB_tree/test/AABB_tree/aabb_correctness_triangle_test.cpp +++ b/AABB_tree/test/AABB_tree/aabb_correctness_triangle_test.cpp @@ -32,7 +32,6 @@ #include #include -#include #include #include diff --git a/AABB_tree/test/AABB_tree/aabb_distance_edge_test.cpp b/AABB_tree/test/AABB_tree/aabb_distance_edge_test.cpp index 3da5b2fa1b7..5c3ba4ca6e1 100644 --- a/AABB_tree/test/AABB_tree/aabb_distance_edge_test.cpp +++ b/AABB_tree/test/AABB_tree/aabb_distance_edge_test.cpp @@ -33,7 +33,6 @@ #include #include -#include #include diff --git a/AABB_tree/test/AABB_tree/aabb_distance_triangle_hint_test.cpp b/AABB_tree/test/AABB_tree/aabb_distance_triangle_hint_test.cpp index 0e248bf8b4e..2c8e715276a 100644 --- a/AABB_tree/test/AABB_tree/aabb_distance_triangle_hint_test.cpp +++ b/AABB_tree/test/AABB_tree/aabb_distance_triangle_hint_test.cpp @@ -33,7 +33,6 @@ #include #include -#include #include diff --git a/AABB_tree/test/AABB_tree/aabb_distance_triangle_test.cpp b/AABB_tree/test/AABB_tree/aabb_distance_triangle_test.cpp index 6dfe77e2594..ff1e2775200 100644 --- a/AABB_tree/test/AABB_tree/aabb_distance_triangle_test.cpp +++ b/AABB_tree/test/AABB_tree/aabb_distance_triangle_test.cpp @@ -29,7 +29,6 @@ #include #include -#include #include #include "AABB_test_util.h" diff --git a/AABB_tree/test/AABB_tree/aabb_intersection_triangle_test.cpp b/AABB_tree/test/AABB_tree/aabb_intersection_triangle_test.cpp index 30121277365..3cdf2b07f8e 100644 --- a/AABB_tree/test/AABB_tree/aabb_intersection_triangle_test.cpp +++ b/AABB_tree/test/AABB_tree/aabb_intersection_triangle_test.cpp @@ -32,7 +32,6 @@ #include #include -#include #include #include diff --git a/AABB_tree/test/AABB_tree/aabb_naive_vs_tree_distance_segment_test.cpp b/AABB_tree/test/AABB_tree/aabb_naive_vs_tree_distance_segment_test.cpp index 85a7a03ad41..acdfe0d2695 100644 --- a/AABB_tree/test/AABB_tree/aabb_naive_vs_tree_distance_segment_test.cpp +++ b/AABB_tree/test/AABB_tree/aabb_naive_vs_tree_distance_segment_test.cpp @@ -33,7 +33,6 @@ #include #include -#include #include #include diff --git a/AABB_tree/test/AABB_tree/aabb_naive_vs_tree_distance_triangle_test.cpp b/AABB_tree/test/AABB_tree/aabb_naive_vs_tree_distance_triangle_test.cpp index 803f7397b50..04f6bbfbb8c 100644 --- a/AABB_tree/test/AABB_tree/aabb_naive_vs_tree_distance_triangle_test.cpp +++ b/AABB_tree/test/AABB_tree/aabb_naive_vs_tree_distance_triangle_test.cpp @@ -35,7 +35,6 @@ #include #include -#include #include #include diff --git a/AABB_tree/test/AABB_tree/aabb_naive_vs_tree_triangle_test.cpp b/AABB_tree/test/AABB_tree/aabb_naive_vs_tree_triangle_test.cpp index 22340369dc9..0035f0b5259 100644 --- a/AABB_tree/test/AABB_tree/aabb_naive_vs_tree_triangle_test.cpp +++ b/AABB_tree/test/AABB_tree/aabb_naive_vs_tree_triangle_test.cpp @@ -34,7 +34,6 @@ #include #include -#include #include #include diff --git a/AABB_tree/test/AABB_tree/aabb_test_ray_intersection.cpp b/AABB_tree/test/AABB_tree/aabb_test_ray_intersection.cpp index 90f6902f679..549f925fb9e 100644 --- a/AABB_tree/test/AABB_tree/aabb_test_ray_intersection.cpp +++ b/AABB_tree/test/AABB_tree/aabb_test_ray_intersection.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include #include diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index ba34eec42ac..6fc6e33b4d8 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -2313,7 +2313,7 @@ namespace CGAL { } - struct Remove : public CGAL::unary_function + struct Remove : public CGAL::cpp98::unary_function { Extract& E; @@ -2451,7 +2451,7 @@ namespace CGAL { namespace AFSR { template - struct Auto_count : public CGAL::unary_function >{ + struct Auto_count : public CGAL::cpp98::unary_function >{ mutable std::size_t i; Auto_count() @@ -2464,7 +2464,7 @@ namespace CGAL { }; template - struct Auto_count_cc : public CGAL::unary_function >{ + struct Auto_count_cc : public CGAL::cpp98::unary_function >{ mutable std::size_t i; CC cc; diff --git a/Algebraic_foundations/include/CGAL/Algebraic_extension_traits.h b/Algebraic_foundations/include/CGAL/Algebraic_extension_traits.h index da663777214..22afb5510bb 100644 --- a/Algebraic_foundations/include/CGAL/Algebraic_extension_traits.h +++ b/Algebraic_foundations/include/CGAL/Algebraic_extension_traits.h @@ -47,7 +47,7 @@ public: //! computes the factor which normalizes a number to be integral after // multiplication class Normalization_factor - : public CGAL::unary_function { + : public CGAL::cpp98::unary_function { private: static Type normalization_factor(const Type&,Integral_domain_without_division_tag){ @@ -68,7 +68,7 @@ public: }; class Denominator_for_algebraic_integers - : public CGAL::unary_function { + : public CGAL::cpp98::unary_function { public: //! determine normalization factor Type operator () (const Type&) { diff --git a/Algebraic_foundations/include/CGAL/Algebraic_structure_traits.h b/Algebraic_foundations/include/CGAL/Algebraic_structure_traits.h index 12d88edb879..174cafb4168 100644 --- a/Algebraic_foundations/include/CGAL/Algebraic_structure_traits.h +++ b/Algebraic_foundations/include/CGAL/Algebraic_structure_traits.h @@ -112,7 +112,7 @@ class Algebraic_structure_traits_base< Type_, Null_tag > { // does nothing by default class Simplify - : public CGAL::unary_function< Type&, void > { + : public CGAL::cpp98::unary_function< Type&, void > { public: void operator()( Type& ) const {} }; @@ -151,7 +151,7 @@ class Algebraic_structure_traits_base< Type_, // returns Type(1) by default class Unit_part - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return( x < Type(0)) ? @@ -160,7 +160,7 @@ class Algebraic_structure_traits_base< Type_, }; class Square - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return x*x; @@ -168,7 +168,7 @@ class Algebraic_structure_traits_base< Type_, }; class Is_zero - : public CGAL::unary_function< Type, bool > { + : public CGAL::cpp98::unary_function< Type, bool > { public: bool operator()( const Type& x ) const { return x == Type(0); @@ -176,7 +176,7 @@ class Algebraic_structure_traits_base< Type_, }; class Is_one - : public CGAL::unary_function< Type, bool > { + : public CGAL::cpp98::unary_function< Type, bool > { public: bool operator()( const Type& x ) const { return x == Type(1); @@ -221,7 +221,7 @@ class Algebraic_structure_traits_base< Type_, // Default implementation of Divides functor for unique factorization domains // x divides y if gcd(y,x) equals x up to inverses class Divides - : public CGAL::binary_function{ + : public CGAL::cpp98::binary_function{ public: bool operator()( const Type& x, const Type& y) const { typedef CGAL::Algebraic_structure_traits AST; @@ -257,7 +257,7 @@ class Algebraic_structure_traits_base< Type_, // maps to \c Div by default. class Integral_division - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( @@ -279,7 +279,7 @@ class Algebraic_structure_traits_base< Type_, // Algorithm from NiX/euclids_algorithm.h class Gcd - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( @@ -372,7 +372,7 @@ class Algebraic_structure_traits_base< Type_, // based on \c Div_mod. class Div - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, @@ -390,7 +390,7 @@ class Algebraic_structure_traits_base< Type_, // based on \c Div_mod. class Mod - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, @@ -408,7 +408,7 @@ class Algebraic_structure_traits_base< Type_, // Divides for Euclidean Ring class Divides - : public CGAL::binary_function{ + : public CGAL::cpp98::binary_function{ public: bool operator()( const Type& x, const Type& y) const { typedef Algebraic_structure_traits AST; @@ -448,7 +448,7 @@ class Algebraic_structure_traits_base< Type_, Field_tag > // returns the argument \a a by default class Unit_part - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return( x == Type(0)) ? Type(1) : x; @@ -456,7 +456,7 @@ class Algebraic_structure_traits_base< Type_, Field_tag > }; // maps to \c operator/ by default. class Integral_division - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, @@ -475,7 +475,7 @@ class Algebraic_structure_traits_base< Type_, Field_tag > // maps to \c 1/x by default. class Inverse - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return Type(1)/x; @@ -487,7 +487,7 @@ class Algebraic_structure_traits_base< Type_, Field_tag > // returns always true // \pre: x != 0 class Divides - : public CGAL::binary_function< Type, Type, bool > { + : public CGAL::cpp98::binary_function< Type, Type, bool > { public: bool operator()( const Type& CGAL_precondition_code(x), const Type& /* y */) const { CGAL_precondition_code( typedef Algebraic_structure_traits AST); @@ -523,7 +523,7 @@ class Algebraic_structure_traits_base< Type_, typedef Field_with_sqrt_tag Algebraic_category; struct Is_square - :public CGAL::binary_function + :public CGAL::cpp98::binary_function { bool operator()(const Type& ) const {return true;} bool operator()( @@ -580,7 +580,7 @@ class Algebraic_structure_traits_base< Type_, namespace INTERN_AST { template< class Type > class Div_per_operator - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, @@ -593,7 +593,7 @@ namespace INTERN_AST { template< class Type > class Mod_per_operator - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, @@ -606,7 +606,7 @@ namespace INTERN_AST { template< class Type > class Is_square_per_sqrt - : public CGAL::binary_function< Type, Type&, + : public CGAL::cpp98::binary_function< Type, Type&, bool > { public: bool operator()( const Type& x, diff --git a/Algebraic_foundations/include/CGAL/Real_embeddable_traits.h b/Algebraic_foundations/include/CGAL/Real_embeddable_traits.h index 4c649acb590..e7f4f343b14 100644 --- a/Algebraic_foundations/include/CGAL/Real_embeddable_traits.h +++ b/Algebraic_foundations/include/CGAL/Real_embeddable_traits.h @@ -37,7 +37,7 @@ struct Is_zero_selector{ typedef AST_is_zero Type; }; template< class T > struct Is_zero_selector< T, Null_functor > { - struct Type : public CGAL::unary_function< T, bool >{ + struct Type : public CGAL::cpp98::unary_function< T, bool >{ bool operator()( const T& x ) const { return x == T(0); } @@ -81,7 +81,7 @@ public: Is_zero; //! The generic \c Is_finite functor returns true - class Is_finite : public CGAL::unary_function< Type, Boolean > { + class Is_finite : public CGAL::cpp98::unary_function< Type, Boolean > { public: Boolean operator()( const Type& ) const { return true; @@ -91,7 +91,7 @@ public: //! The generic \c Abs functor implementation //! uses one comparisons and the unary minus if necessary. class Abs - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: //! the function call. Type operator()( const Type& x ) const { @@ -101,7 +101,7 @@ public: //! The generic \c Sgn functor implementation uses two comparisons. class Sgn - : public CGAL::unary_function< Type, ::CGAL::Sign > { + : public CGAL::cpp98::unary_function< Type, ::CGAL::Sign > { public: //! the function call. ::CGAL::Sign operator()( const Type& x ) const { @@ -115,7 +115,7 @@ public: //! The generic \c Is_positive functor implementation uses one comparison. class Is_positive - : public CGAL::unary_function< Type, Boolean > { + : public CGAL::cpp98::unary_function< Type, Boolean > { public: //! the function call. Boolean operator()( const Type& x ) const { @@ -125,7 +125,7 @@ public: //! The generic \c Is_negative functor implementation uses one comparison. class Is_negative - : public CGAL::unary_function< Type, Boolean > { + : public CGAL::cpp98::unary_function< Type, Boolean > { public: //! the function call. Boolean operator()( const Type& x ) const { @@ -135,7 +135,7 @@ public: //! The generic \c Compare functor implementation uses two comparisons. class Compare - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Comparison_result > { public: //! the function call. @@ -152,7 +152,7 @@ public: Comparison_result ) }; - class To_double : public CGAL::unary_function< Type, double > { + class To_double : public CGAL::cpp98::unary_function< Type, double > { public: double operator()( const Type& x ) const { return static_cast(x); @@ -160,7 +160,7 @@ public: }; class To_interval - : public CGAL::unary_function< Type, std::pair > { + : public CGAL::cpp98::unary_function< Type, std::pair > { public: std::pair operator()( const Type& x ) const { double dx(static_cast(x)); diff --git a/Algebraic_foundations/include/CGAL/number_utils_classes.h b/Algebraic_foundations/include/CGAL/number_utils_classes.h index afac55bbf35..d783df4ef4b 100644 --- a/Algebraic_foundations/include/CGAL/number_utils_classes.h +++ b/Algebraic_foundations/include/CGAL/number_utils_classes.h @@ -102,7 +102,7 @@ struct Is_zero : namespace internal { template struct Compare_base: public Compare {}; template struct Compare_base - :public CGAL::binary_function< NT, NT, Comparison_result > { + :public CGAL::cpp98::binary_function< NT, NT, Comparison_result > { Comparison_result operator()( const NT& x, const NT& y) const { if (x < y) return SMALLER; diff --git a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Algebraic_curve_kernel_2.h b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Algebraic_curve_kernel_2.h index adcd86758f9..dec15ae0fd9 100644 --- a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Algebraic_curve_kernel_2.h +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Algebraic_curve_kernel_2.h @@ -194,7 +194,7 @@ protected: //! polynomial canonicalizer, needed for the cache template - struct Poly_canonicalizer : public CGAL::unary_function< Poly, Poly > + struct Poly_canonicalizer : public CGAL::cpp98::unary_function< Poly, Poly > { // use Polynomial_traits_d<>::Canonicalize ? Poly operator()(Poly p) @@ -356,7 +356,7 @@ public: // Composition of two unary functors template class Unary_compose - : public CGAL::unary_function { public: @@ -419,7 +419,7 @@ public: * when appropriate */ class Construct_curve_2 : - public CGAL::unary_function< Polynomial_2, Curve_analysis_2 > { + public CGAL::cpp98::unary_function< Polynomial_2, Curve_analysis_2 > { public: @@ -443,7 +443,7 @@ public: * caching is used when appropriate */ class Construct_curve_pair_2 : - public CGAL::binary_function { public: @@ -636,7 +636,7 @@ public: class Compute_polynomial_x_2 : - public CGAL::unary_function { + public CGAL::cpp98::unary_function { public: @@ -656,7 +656,7 @@ public: compute_polynomial_x_2_object); class Compute_polynomial_y_2 : - public CGAL::unary_function { + public CGAL::cpp98::unary_function { public: @@ -676,7 +676,7 @@ public: compute_polynomial_y_2_object); - class Isolate_x_2 : public CGAL::binary_function > { @@ -699,7 +699,7 @@ public: CGAL_Algebraic_Kernel_cons(Isolate_x_2, isolate_x_2_object); - class Isolate_y_2 : public CGAL::binary_function > { @@ -887,7 +887,7 @@ public: //! returns the x-coordinate of an \c Algebraic_real_2 object class Compute_x_2 : - public CGAL::unary_function { + public CGAL::cpp98::unary_function { public: @@ -922,7 +922,7 @@ public: * return approximation of the y-coordinate. */ class Compute_y_2 : - public CGAL::unary_function { + public CGAL::cpp98::unary_function { public: @@ -945,7 +945,7 @@ public: #endif class Approximate_absolute_x_2 - : public CGAL::binary_function >{ + : public CGAL::cpp98::binary_function >{ public: @@ -968,7 +968,7 @@ public: approximate_absolute_x_2_object); class Approximate_relative_x_2 - : public CGAL::binary_function >{ + : public CGAL::cpp98::binary_function >{ public: @@ -990,7 +990,7 @@ public: approximate_relative_x_2_object); class Approximate_absolute_y_2 - : public CGAL::binary_function >{ + : public CGAL::cpp98::binary_function >{ public: @@ -1020,7 +1020,7 @@ public: approximate_absolute_y_2_object); class Approximate_relative_y_2 - : public CGAL::binary_function >{ + : public CGAL::cpp98::binary_function >{ public: @@ -1171,7 +1171,7 @@ public: //! \brief comparison of x-coordinates class Compare_x_2 : - public CGAL::binary_function { public: @@ -1264,7 +1264,7 @@ public: * If possible, it is recommended to avoid this functor for efficiency.} */ class Compare_y_2 : - public CGAL::binary_function< Algebraic_real_2, Algebraic_real_2, + public CGAL::cpp98::binary_function< Algebraic_real_2, Algebraic_real_2, Comparison_result > { public: @@ -1376,7 +1376,7 @@ public: * to have equal x-coordinates, thus only the y-coordinates are compared. */ class Compare_xy_2 : - public CGAL::binary_function { public: @@ -1507,7 +1507,7 @@ public: * the polynomial \c p is square free. */ class Has_finite_number_of_self_intersections_2 : - public CGAL::unary_function< Polynomial_2, bool > { + public CGAL::cpp98::unary_function< Polynomial_2, bool > { public: @@ -1536,7 +1536,7 @@ public: * the two polynomials \c f and \c g are coprime. */ class Has_finite_number_of_intersections_2 : - public CGAL::binary_function< Polynomial_2, Polynomial_2, bool > { + public CGAL::cpp98::binary_function< Polynomial_2, Polynomial_2, bool > { public: @@ -1720,7 +1720,7 @@ public: //! Non-Algebraic name typedef Algebraic_real_2 Coordinate_2; - class Is_square_free_2 : public CGAL::unary_function { + class Is_square_free_2 : public CGAL::cpp98::unary_function { public: @@ -1742,7 +1742,7 @@ public: typedef Has_finite_number_of_intersections_2 Is_coprime_2; CGAL_Algebraic_Kernel_cons(Is_coprime_2, is_coprime_2_object); - class Make_square_free_2 : public CGAL::unary_function { public: @@ -1807,9 +1807,9 @@ public: * In pariticular, each singular point is x-critical. */ class X_critical_points_2 : - public CGAL::binary_function< Curve_analysis_2, - CGAL::iterator, - CGAL::iterator > { + public CGAL::cpp98::binary_function< Curve_analysis_2, + CGAL::cpp98::iterator, + CGAL::cpp98::iterator > { public: @@ -1886,9 +1886,9 @@ public: * In pariticular, each singular point is y-critical. */ class Y_critical_points_2 : - public CGAL::binary_function< Curve_analysis_2, - CGAL::iterator, - CGAL::iterator > { + public CGAL::cpp98::binary_function< Curve_analysis_2, + CGAL::cpp98::iterator, + CGAL::cpp98::iterator > { public: @@ -1981,7 +1981,7 @@ public: // Overload the Sign_at_1 functor, to enable filter steps in the // Curve analysis in a coherent way class Sign_at_1 - : public::CGAL::binary_function { + : public::CGAL::cpp98::binary_function { public: @@ -2058,7 +2058,7 @@ public: * curve. Returns a value convertible to \c CGAL::Sign */ class Sign_at_2 : - public CGAL::binary_function { + public CGAL::cpp98::binary_function { public: @@ -2154,7 +2154,7 @@ public: CGAL_Algebraic_Kernel_pred(Sign_at_2, sign_at_2_object); class Is_zero_at_2 - : public CGAL::binary_function { + : public CGAL::cpp98::binary_function { public: @@ -2498,7 +2498,7 @@ public: CGAL_Algebraic_Kernel_cons(Solve_2, solve_2_object); class Number_of_solutions_2 - : public CGAL::binary_function { + : public CGAL::cpp98::binary_function { public: @@ -2524,7 +2524,7 @@ public: // Functor used to evaluate a Polynomial_2 in a Bound, up to a // constant factor class Evaluate_utcf_2 - : public CGAL::binary_function { + : public CGAL::cpp98::binary_function { public: @@ -2600,7 +2600,7 @@ public: //! Refines the x-coordinate of an Algebraic_real_2 object class Refine_x_2 : - public CGAL::unary_function { + public CGAL::cpp98::unary_function { public: @@ -2624,7 +2624,7 @@ public: CGAL_Algebraic_Kernel_pred(Refine_x_2, refine_x_2_object); class Refine_y_2 : - public CGAL::unary_function { + public CGAL::cpp98::unary_function { public: diff --git a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Algebraic_real_d_1.h b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Algebraic_real_d_1.h index c7d755b1dbe..26d5fee93e3 100644 --- a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Algebraic_real_d_1.h +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Algebraic_real_d_1.h @@ -385,7 +385,7 @@ public: typedef internal::Algebraic_real_d_1< Coefficient, Rational, HandlePolicy, RepClass > Type; class Compare - : public CGAL::binary_function< Type, Type, CGAL::Comparison_result > { + : public CGAL::cpp98::binary_function< Type, Type, CGAL::Comparison_result > { public: CGAL::Comparison_result operator()( const Type& a, const Type& b ) const { return a.compare( b ); } @@ -414,7 +414,7 @@ public: }; class Sgn - : public CGAL::unary_function< Type, CGAL::Sign > { + : public CGAL::cpp98::unary_function< Type, CGAL::Sign > { public: CGAL::Sign operator()( const Type& a ) const { return a.compare( Rational(0) ); @@ -422,7 +422,7 @@ public: }; class To_double - : public CGAL::unary_function< Type, double > { + : public CGAL::cpp98::unary_function< Type, double > { public: double operator()(const Type& a) const { return a.to_double(); @@ -430,7 +430,7 @@ public: }; class To_interval - : public CGAL::unary_function< Type, std::pair > { + : public CGAL::cpp98::unary_function< Type, std::pair > { public: typename std::pair operator()(const Type& a) const { return a.to_interval(); diff --git a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Bitstream_coefficient_kernel.h b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Bitstream_coefficient_kernel.h index 6f2e5faa2ea..1e1d9eadb7c 100644 --- a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Bitstream_coefficient_kernel.h +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Bitstream_coefficient_kernel.h @@ -50,7 +50,7 @@ template struct Bitstream_coefficient_kernel { return Is_zero(); } - struct Convert_to_bfi : public CGAL::unary_function + struct Convert_to_bfi : public CGAL::cpp98::unary_function { Bigfloat_interval operator() (Coefficient c) const { diff --git a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Bitstream_coefficient_kernel_at_alpha.h b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Bitstream_coefficient_kernel_at_alpha.h index 3435ded47b2..ec11b08d989 100644 --- a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Bitstream_coefficient_kernel_at_alpha.h +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Bitstream_coefficient_kernel_at_alpha.h @@ -120,7 +120,7 @@ public: //! \name Functors //! @{ - struct Is_zero : public CGAL::unary_function { + struct Is_zero : public CGAL::cpp98::unary_function { Is_zero(Algebraic_kernel_d_1* kernel,Algebraic_real_1 alpha) : _m_kernel(kernel),_m_alpha(alpha) {} @@ -140,7 +140,7 @@ public: } struct Convert_to_bfi - : public CGAL::unary_function { + : public CGAL::cpp98::unary_function { Convert_to_bfi(Algebraic_kernel_d_1* kernel, Algebraic_real_1 alpha) diff --git a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Curve_analysis_2.h b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Curve_analysis_2.h index 98255ec6077..f77a1c6912b 100644 --- a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Curve_analysis_2.h +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Curve_analysis_2.h @@ -108,7 +108,7 @@ template }; template struct Compare_for_vert_line_map - : public CGAL::binary_function { + : public CGAL::cpp98::binary_function { BOOST_MPL_HAS_XXX_TRAIT_DEF(T) BOOST_MPL_HAS_XXX_TRAIT_DEF(Handle_policy) diff --git a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Float_traits.h b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Float_traits.h index f95e4396070..3536c378ae0 100644 --- a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Float_traits.h +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Float_traits.h @@ -66,7 +66,7 @@ template<> class Float_traits< leda_bigfloat > { public: struct Get_mantissa - : public CGAL::unary_function< leda_bigfloat, leda_integer > { + : public CGAL::cpp98::unary_function< leda_bigfloat, leda_integer > { leda_integer operator()( const leda_bigfloat& x ) const { //std::cout << x.get_significant() << std::endl; return x.get_significant(); @@ -74,14 +74,14 @@ public: }; struct Get_exponent - : public CGAL::unary_function< leda_bigfloat, long > { + : public CGAL::cpp98::unary_function< leda_bigfloat, long > { long operator()( const leda_bigfloat& x ) const { return x.get_exponent().to_long(); } }; struct Mul_by_pow_of_2 - : public CGAL::binary_function< leda_bigfloat, long, leda_bigfloat> { + : public CGAL::cpp98::binary_function< leda_bigfloat, long, leda_bigfloat> { leda_bigfloat operator()( const leda_bigfloat& a, long e ) const { return leda_bigfloat(a.get_significant(), a.get_exponent()+e); } @@ -98,21 +98,21 @@ class Float_traits< CORE::BigFloat > { public: struct Get_mantissa - : public CGAL::unary_function< CORE::BigFloat, CORE::BigInt > { + : public CGAL::cpp98::unary_function< CORE::BigFloat, CORE::BigInt > { CORE::BigInt operator()( const CORE::BigFloat& x ) const { return x.m(); } }; struct Get_exponent - : public CGAL::unary_function< CORE::BigFloat, long > { + : public CGAL::cpp98::unary_function< CORE::BigFloat, long > { long operator()( const CORE::BigFloat& x ) const { return CORE::CHUNK_BIT*x.exp(); // The basis is 2^CORE::CHUNK_BIT } }; struct Mul_by_pow_of_2 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function < CORE::BigFloat, long , CORE::BigFloat> { CORE::BigFloat operator()( const CORE::BigFloat& a, long e ) const { return a*CORE::BigFloat::exp2(e); @@ -127,7 +127,7 @@ public: template<> class Float_traits< Gmpfr > { struct Get_mantissa_exponent - : public CGAL::unary_function< Gmpfr, std::pair > { + : public CGAL::cpp98::unary_function< Gmpfr, std::pair > { std::pair operator()( const Gmpfr& x ) const { return x.to_integer_exp(); @@ -135,21 +135,21 @@ template<> class Float_traits< Gmpfr > { }; public: struct Get_mantissa - : public CGAL::unary_function< Gmpfr, Gmpz > { + : public CGAL::cpp98::unary_function< Gmpfr, Gmpz > { Gmpz operator()( const Gmpfr& x ) const { return Get_mantissa_exponent()(x).first; } }; struct Get_exponent - : public CGAL::unary_function< Gmpfr, long > { + : public CGAL::cpp98::unary_function< Gmpfr, long > { long operator()( const Gmpfr& x ) const { return Get_mantissa_exponent()(x).second; } }; struct Mul_by_pow_of_2 - : public CGAL::binary_function< Gmpfr, Gmpz, Gmpfr> { + : public CGAL::cpp98::binary_function< Gmpfr, Gmpz, Gmpfr> { Gmpfr operator()( const Gmpfr& a, long e ) const { Gmpfr result(0,a.get_precision()); // just to get the prec of a if (e >= 0 ){ diff --git a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Interval_evaluate_1.h b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Interval_evaluate_1.h index a0627db9b65..a3438c72dc7 100644 --- a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Interval_evaluate_1.h +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Interval_evaluate_1.h @@ -39,7 +39,7 @@ namespace CGAL { namespace internal { template -struct Interval_evaluate_1 : public CGAL::binary_function +struct Interval_evaluate_1 : public CGAL::cpp98::binary_function , std::pair::Coefficient_type,Bound>::Type, diff --git a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Interval_evaluate_2.h b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Interval_evaluate_2.h index 1d0b57bf8d6..0078b698e58 100644 --- a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Interval_evaluate_2.h +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Interval_evaluate_2.h @@ -40,7 +40,7 @@ namespace CGAL { namespace internal { template -struct Interval_evaluate_2 : public CGAL::binary_function +struct Interval_evaluate_2 : public CGAL::cpp98::binary_function , std::pair::Innermost_coefficient_type,Bound>::Type, typename CGAL::Coercion_traits::Innermost_coefficient_type,Bound>::Type> > { diff --git a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Real_embeddable_extension.h b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Real_embeddable_extension.h index 156c2121576..509d9cd5cbb 100644 --- a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Real_embeddable_extension.h +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Real_embeddable_extension.h @@ -103,7 +103,7 @@ template<> class Real_embeddable_extension< long > { public: struct Ceil_log2_abs - : public CGAL::unary_function< long, long > { + : public CGAL::cpp98::unary_function< long, long > { long operator()( long x ) { if (x < 0) x = -x; CGAL_precondition(x > 0); @@ -113,7 +113,7 @@ public: }; struct Floor_log2_abs - : public CGAL::unary_function< long, long > { + : public CGAL::cpp98::unary_function< long, long > { private: signed char floor_log2_4bit[16]; public: @@ -149,11 +149,11 @@ public: }; struct Floor - : public CGAL::unary_function< long, long > { + : public CGAL::cpp98::unary_function< long, long > { long operator() (long x) { return x;} }; struct Ceil - : public CGAL::unary_function< long, long > { + : public CGAL::cpp98::unary_function< long, long > { long operator() (long x) { return x;} }; }; @@ -168,7 +168,7 @@ public: typedef leda_integer Type; struct Ceil_log2_abs - : public CGAL::unary_function< leda_integer, long > { + : public CGAL::cpp98::unary_function< leda_integer, long > { long operator()( const leda_integer& x ) const { CGAL_precondition(x != leda_integer(0)); ::leda::digit_sz ldgzeros = ::leda::digLeadingZeros(x.highword()); @@ -188,7 +188,7 @@ public: }; struct Floor_log2_abs - : public CGAL::unary_function< leda_integer, long > { + : public CGAL::cpp98::unary_function< leda_integer, long > { long operator()( const leda_integer& x ) const { CGAL_precondition(x != leda_integer(0)); ::leda::digit_sz ldgzeros @@ -200,11 +200,11 @@ public: }; struct Floor - : public CGAL::unary_function< leda_integer, leda_integer > { + : public CGAL::cpp98::unary_function< leda_integer, leda_integer > { leda_integer operator() (const leda_integer& x) const { return x;} }; struct Ceil - : public CGAL::unary_function< leda_integer, leda_integer > { + : public CGAL::cpp98::unary_function< leda_integer, leda_integer > { leda_integer operator() (const leda_integer& x) const { return x;} }; }; @@ -216,7 +216,7 @@ public: typedef leda_bigfloat Type; struct Floor_log2_abs - : public CGAL::unary_function< leda_bigfloat, long > { + : public CGAL::cpp98::unary_function< leda_bigfloat, long > { long operator()( const leda_bigfloat& x ) const { CGAL_precondition(CGAL::sign(x) != CGAL::ZERO); ::leda::integer abs_sign = abs(x.get_significant()); @@ -226,7 +226,7 @@ public: }; struct Ceil_log2_abs - : public CGAL::unary_function< leda_bigfloat, long > { + : public CGAL::cpp98::unary_function< leda_bigfloat, long > { long operator()( const leda_bigfloat& x ) const { CGAL_precondition(CGAL::sign(x) != CGAL::ZERO); return ::leda::ilog2(x).to_long(); @@ -234,14 +234,14 @@ public: }; struct Floor - : public CGAL::unary_function< leda_bigfloat, leda_integer > { + : public CGAL::cpp98::unary_function< leda_bigfloat, leda_integer > { leda_integer operator() ( const leda_bigfloat& x ) const { return leda::to_integer( x, leda::TO_N_INF ); } }; struct Ceil - : public CGAL::unary_function< leda_bigfloat, leda_integer > { + : public CGAL::cpp98::unary_function< leda_bigfloat, leda_integer > { leda_integer operator() ( const leda_bigfloat& x ) const { return leda::to_integer( x, leda::TO_P_INF ); } @@ -255,7 +255,7 @@ public: typedef leda_bigfloat_interval Type; struct Floor_log2_abs - : public CGAL::unary_function< leda_bigfloat_interval, long > { + : public CGAL::cpp98::unary_function< leda_bigfloat_interval, long > { result_type operator() (const argument_type& x) const { CGAL_precondition(! ::boost::numeric::in_zero(x)); @@ -264,7 +264,7 @@ public: }; struct Ceil_log2_abs - : public CGAL::unary_function< leda_bigfloat_interval, long > { + : public CGAL::cpp98::unary_function< leda_bigfloat_interval, long > { long operator()( const leda_bigfloat_interval& x ) const { CGAL_precondition(!(::boost::numeric::in_zero(x) && ::boost::numeric::singleton(x))); @@ -273,7 +273,7 @@ public: }; struct Floor - : public CGAL::unary_function< leda_bigfloat_interval, leda_integer > { + : public CGAL::cpp98::unary_function< leda_bigfloat_interval, leda_integer > { leda_integer operator() ( const leda_bigfloat_interval& x ) const { return internal::floor( x.lower() ); @@ -281,7 +281,7 @@ public: }; struct Ceil - : public CGAL::unary_function< leda_bigfloat_interval, leda_integer > { + : public CGAL::cpp98::unary_function< leda_bigfloat_interval, leda_integer > { leda_integer operator() ( const leda_bigfloat_interval& x ) const { return internal::ceil( x.upper() ); @@ -299,27 +299,27 @@ class Real_embeddable_extension< CORE::BigInt > { public: typedef CORE::BigInt Type; struct Floor_log2_abs - : public CGAL::unary_function< CORE::BigInt, long > { + : public CGAL::cpp98::unary_function< CORE::BigInt, long > { long operator()( const CORE::BigInt& x ) const { return CORE::floorLg(x); } }; struct Ceil_log2_abs - : public CGAL::unary_function< CORE::BigInt, long > { + : public CGAL::cpp98::unary_function< CORE::BigInt, long > { long operator()( const CORE::BigInt& x ) const { return CORE::ceilLg(x); } }; struct Floor - : public CGAL::unary_function< CORE::BigInt, CORE::BigInt > { + : public CGAL::cpp98::unary_function< CORE::BigInt, CORE::BigInt > { CORE::BigInt operator() (const CORE::BigInt& x) const { return x; } }; struct Ceil - : public CGAL::unary_function< CORE::BigInt, CORE::BigInt > { + : public CGAL::cpp98::unary_function< CORE::BigInt, CORE::BigInt > { CORE::BigInt operator() (const CORE::BigInt& x) const { return x; } @@ -332,7 +332,7 @@ class Real_embeddable_extension< CORE::BigFloat > { public: typedef CORE::BigFloat Type; struct Floor_log2_abs - : public CGAL::unary_function< CORE::BigFloat, long > { + : public CGAL::cpp98::unary_function< CORE::BigFloat, long > { long operator()( CORE::BigFloat x ) const { CGAL_precondition(!CGAL::zero_in(x)); x = CGAL::abs(x); @@ -341,7 +341,7 @@ public: }; struct Ceil_log2_abs - : public CGAL::unary_function< CORE::BigFloat, long > { + : public CGAL::cpp98::unary_function< CORE::BigFloat, long > { long operator()( CORE::BigFloat x ) const { // (already commented out in EXACUS)... // NiX_precond(!(NiX::in_zero(x) && NiX::singleton(x))); @@ -351,7 +351,7 @@ public: }; struct Floor - : public CGAL::unary_function< CORE::BigFloat, CORE::BigInt > { + : public CGAL::cpp98::unary_function< CORE::BigFloat, CORE::BigInt > { CORE::BigInt operator() ( const CORE::BigFloat& x ) const { CORE::BigInt xi = x.BigIntValue(); if(x.sign() < 0 && x.cmp(xi)!=0) { @@ -362,7 +362,7 @@ public: }; struct Ceil - : public CGAL::unary_function< CORE::BigFloat, CORE::BigInt > { + : public CGAL::cpp98::unary_function< CORE::BigFloat, CORE::BigInt > { CORE::BigInt operator() ( const CORE::BigFloat& x ) const { CORE::BigInt xi = x.BigIntValue(); if(x.sign() >0 && x.cmp(xi)!=0) { @@ -385,7 +385,7 @@ public: typedef Gmpz Type; struct Floor_log2_abs - : public CGAL::unary_function< Gmpz, long > { + : public CGAL::cpp98::unary_function< Gmpz, long > { long operator()( const Gmpz& x ) const { CGAL_precondition(!CGAL::is_zero(x)); return static_cast(mpz_sizeinbase(x.mpz(),2)-1); @@ -393,7 +393,7 @@ public: }; struct Ceil_log2_abs - : public CGAL::unary_function< Gmpz, long > { + : public CGAL::cpp98::unary_function< Gmpz, long > { long operator()( const Gmpz& x ) const { long pos = mpz_scan1(x.mpz(),0); long size = static_cast(mpz_sizeinbase(x.mpz(),2)); @@ -405,13 +405,13 @@ public: }; struct Floor - : public CGAL::unary_function< Gmpz, Gmpz > { + : public CGAL::cpp98::unary_function< Gmpz, Gmpz > { Gmpz operator() (const Gmpz& x) const { return x; } }; struct Ceil - : public CGAL::unary_function< Gmpz, Gmpz > { + : public CGAL::cpp98::unary_function< Gmpz, Gmpz > { Gmpz operator() (const Gmpz& x) const { return x; } @@ -427,7 +427,7 @@ public: typedef Gmpfr Type; struct Floor_log2_abs - : public CGAL::unary_function< Gmpfr, long > { + : public CGAL::cpp98::unary_function< Gmpfr, long > { long operator()( const Gmpfr& x ) const { Float_traits::Get_mantissa get_mantissa; Float_traits::Get_exponent get_exponent; @@ -438,7 +438,7 @@ public: }; struct Ceil_log2_abs - : public CGAL::unary_function< Gmpfr, long > { + : public CGAL::cpp98::unary_function< Gmpfr, long > { long operator()( const Gmpfr& x ) const { Float_traits::Get_mantissa get_mantissa; Float_traits::Get_exponent get_exponent; @@ -449,7 +449,7 @@ public: }; struct Floor - : public CGAL::unary_function< Gmpfr, Gmpz > { + : public CGAL::cpp98::unary_function< Gmpfr, Gmpz > { Gmpz operator() ( const Gmpfr& x ) const { Gmpz result; mpfr_get_z (result.mpz(),x.fr(),GMP_RNDD); @@ -458,7 +458,7 @@ public: }; struct Ceil - : public CGAL::unary_function< Gmpfr, Gmpz > { + : public CGAL::cpp98::unary_function< Gmpfr, Gmpz > { Gmpz operator() ( const Gmpfr& x ) const { Gmpz result; mpfr_get_z (result.mpz(),x.fr(),GMP_RNDU); @@ -476,7 +476,7 @@ public: typedef Gmpfi Type; struct Floor_log2_abs - : public CGAL::unary_function< Gmpfi, long > { + : public CGAL::cpp98::unary_function< Gmpfi, long > { result_type operator() (const argument_type& x) const { CGAL_precondition(!x.is_zero()); return internal::floor_log2_abs(x.abs().inf()); @@ -484,7 +484,7 @@ public: }; struct Ceil_log2_abs - : public CGAL::unary_function< Gmpfi, long > { + : public CGAL::cpp98::unary_function< Gmpfi, long > { long operator()( const Gmpfi& x ) const { CGAL_precondition(!x.inf().is_zero() || !x.sup().is_zero()); return internal::ceil_log2_abs(x.abs().sup()); @@ -492,7 +492,7 @@ public: }; struct Floor - : public CGAL::unary_function< Gmpfi, Gmpz > { + : public CGAL::cpp98::unary_function< Gmpfi, Gmpz > { Gmpz operator() ( const Gmpfi& x ) const { return internal::floor( x.inf() ); @@ -500,7 +500,7 @@ public: }; struct Ceil - : public CGAL::unary_function< Gmpfi, Gmpz > { + : public CGAL::cpp98::unary_function< Gmpfi, Gmpz > { Gmpz operator() ( const Gmpfi& x ) const { return internal::ceil( x.sup() ); diff --git a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d_1.h b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d_1.h index 905b6d8eba2..69065209bc7 100644 --- a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d_1.h +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d_1.h @@ -71,12 +71,12 @@ protected: // Some functors used for STL calls template - struct Pair_first : public CGAL::unary_function,A> { + struct Pair_first : public CGAL::cpp98::unary_function,A> { A operator() (std::pair pair) const { return pair.first; } }; template - struct Pair_second : public CGAL::unary_function,B> { + struct Pair_second : public CGAL::cpp98::unary_function,B> { B operator() (std::pair pair) const { return pair.second; } }; @@ -86,7 +86,7 @@ public: typedef Algebraic_real_1 Type; struct Bound_between - : public CGAL::binary_function< Type, Type, Bound > { + : public CGAL::cpp98::binary_function< Type, Type, Bound > { Bound operator()( const Type& t1, const Type& t2 ) const { #if CGAL_AK_DONT_USE_SIMPLE_BOUND_BETWEEN @@ -99,21 +99,21 @@ public: }; struct Lower_bound - : public CGAL::unary_function< Type, Bound > { + : public CGAL::cpp98::unary_function< Type, Bound > { Bound operator()( const Type& t ) const { return t.low(); } }; struct Upper_bound - : public CGAL::unary_function< Type, Bound > { + : public CGAL::cpp98::unary_function< Type, Bound > { Bound operator()( const Type& t ) const { return t.high(); } }; struct Refine - : public CGAL::unary_function< Type, void > { + : public CGAL::cpp98::unary_function< Type, void > { void operator()( const Type& t ) const { t.refine(); } @@ -151,7 +151,7 @@ public: }; struct Approximate_absolute_1: - public CGAL::binary_function >{ + public CGAL::cpp98::binary_function >{ std::pair operator()(const Algebraic_real_1& x, int prec) const { Lower_bound lower; @@ -170,7 +170,7 @@ public: }; struct Approximate_relative_1: - public CGAL::binary_function >{ + public CGAL::cpp98::binary_function >{ std::pair operator()(const Algebraic_real_1& x, int prec) const { @@ -201,7 +201,9 @@ public: }; // class Algebraic_real_traits - + + struct Construct_algebraic_real_1; + // Functors of Algebraic_kernel_d_1 struct Solve_1 { public: @@ -278,7 +280,7 @@ public: /* // TODO: Can we avoid to use this? struct Greater_compare : - public CGAL::binary_function { + public CGAL::cpp98::binary_function { bool operator() (const Algebraic_real_1& a, const Algebraic_real_1& b) const { @@ -336,7 +338,7 @@ public: }; class Number_of_solutions_1 - : public CGAL::unary_function { + : public CGAL::cpp98::unary_function { public: @@ -352,7 +354,7 @@ public: struct Sign_at_1 - : public CGAL::binary_function< Polynomial_1, Algebraic_real_1, CGAL::Sign > { + : public CGAL::cpp98::binary_function< Polynomial_1, Algebraic_real_1, CGAL::Sign > { CGAL::Sign operator()( const Polynomial_1& p, const Algebraic_real_1& ar ) const { if(CGAL::is_zero(p)) return ZERO; if(CGAL::degree(p)==0) return p.sign_at(0); @@ -375,7 +377,7 @@ public: } }; struct Is_zero_at_1 - : public CGAL::binary_function< Polynomial_1, Algebraic_real_1, bool > { + : public CGAL::cpp98::binary_function< Polynomial_1, Algebraic_real_1, bool > { bool operator()( const Polynomial_1& p, const Algebraic_real_1& ar ) const { if(CGAL::is_zero(p)) return true; if( ar.low() == ar.high() ) return p.sign_at( ar.low() ) == ZERO; @@ -385,7 +387,7 @@ public: }; struct Is_square_free_1 - : public CGAL::unary_function< Polynomial_1, bool > { + : public CGAL::cpp98::unary_function< Polynomial_1, bool > { bool operator()( const Polynomial_1& p ) const { typename CGAL::Polynomial_traits_d< Polynomial_1 >::Is_square_free isf; return isf(p); @@ -393,7 +395,7 @@ public: }; struct Is_coprime_1 - : public CGAL::binary_function< Polynomial_1, Polynomial_1, bool > { + : public CGAL::cpp98::binary_function< Polynomial_1, Polynomial_1, bool > { bool operator()( const Polynomial_1& p1, const Polynomial_1& p2 ) const { typename CGAL::Polynomial_traits_d< Polynomial_1 >::Total_degree total_degree; @@ -403,7 +405,7 @@ public: }; struct Make_square_free_1 - : public CGAL::unary_function< Polynomial_1, Polynomial_1 > { + : public CGAL::cpp98::unary_function< Polynomial_1, Polynomial_1 > { Polynomial_1 operator()( const Polynomial_1& p ) const { return typename CGAL::Polynomial_traits_d< Polynomial_1 >::Make_square_free()( p ); } @@ -438,7 +440,7 @@ public: } }; - struct Compute_polynomial_1 : public CGAL::unary_function { Polynomial_1 operator()(const Algebraic_real_1& x) const { return x.polynomial(); @@ -488,7 +490,7 @@ public: }; struct Compare_1 - : public CGAL::binary_function{ @@ -533,7 +535,7 @@ public: public: - struct Isolate_1 : public CGAL::binary_function + struct Isolate_1 : public CGAL::cpp98::binary_function < Algebraic_real_1,Polynomial_1,std::pair > { public: diff --git a/Algebraic_kernel_d/include/CGAL/RS/algebraic_1.h b/Algebraic_kernel_d/include/CGAL/RS/algebraic_1.h index c2ac86169bf..0444ed91de4 100644 --- a/Algebraic_kernel_d/include/CGAL/RS/algebraic_1.h +++ b/Algebraic_kernel_d/include/CGAL/RS/algebraic_1.h @@ -259,39 +259,39 @@ public INTERN_RET::Real_embeddable_traits_base< Base; typedef typename Base::Compare Compare; - class Sgn:public CGAL::unary_function{ + class Sgn:public CGAL::cpp98::unary_function{ public: CGAL::Sign operator()(const Type &a)const{ return Compare()(a,Type(0)); } }; - class To_double:public CGAL::unary_function{ + class To_double:public CGAL::cpp98::unary_function{ public: double operator()(const Type &a)const{return a.to_double();} }; class To_interval: - public CGAL::unary_function >{ + public CGAL::cpp98::unary_function >{ public: std::pair operator()(const Type &a)const{ return a.to_interval(); } }; - class Is_zero:public CGAL::unary_function{ + class Is_zero:public CGAL::cpp98::unary_function{ public: bool operator()(const Type &a)const{ return Sgn()(a)==CGAL::ZERO; } }; - class Is_finite:public CGAL::unary_function{ + class Is_finite:public CGAL::cpp98::unary_function{ public: bool operator()(const Type&)const{return true;} }; - class Abs:public CGAL::unary_function{ + class Abs:public CGAL::cpp98::unary_function{ public: Type operator()(const Type &a)const{ return Sgn()(a)==CGAL::NEGATIVE?-a:a; diff --git a/Algebraic_kernel_d/include/CGAL/RS/algebraic_z_1.h b/Algebraic_kernel_d/include/CGAL/RS/algebraic_z_1.h index b8403f363b1..288d68daba0 100644 --- a/Algebraic_kernel_d/include/CGAL/RS/algebraic_z_1.h +++ b/Algebraic_kernel_d/include/CGAL/RS/algebraic_z_1.h @@ -250,39 +250,39 @@ public INTERN_RET::Real_embeddable_traits_base< Base; typedef typename Base::Compare Compare; - class Sgn:public CGAL::unary_function{ + class Sgn:public CGAL::cpp98::unary_function{ public: CGAL::Sign operator()(const Type &a)const{ return Compare()(a,Type(0)); } }; - class To_double:public CGAL::unary_function{ + class To_double:public CGAL::cpp98::unary_function{ public: double operator()(const Type &a)const{return a.to_double();} }; class To_interval: - public CGAL::unary_function >{ + public CGAL::cpp98::unary_function >{ public: std::pair operator()(const Type &a)const{ return a.to_interval(); } }; - class Is_zero:public CGAL::unary_function{ + class Is_zero:public CGAL::cpp98::unary_function{ public: bool operator()(const Type &a)const{ return Sgn()(a)==CGAL::ZERO; } }; - class Is_finite:public CGAL::unary_function{ + class Is_finite:public CGAL::cpp98::unary_function{ public: bool operator()(const Type&)const{return true;} }; - class Abs:public CGAL::unary_function{ + class Abs:public CGAL::cpp98::unary_function{ public: Type operator()(const Type &a)const{ return Sgn()(a)==CGAL::NEGATIVE?-a:a; diff --git a/Algebraic_kernel_d/include/CGAL/RS/functors_1.h b/Algebraic_kernel_d/include/CGAL/RS/functors_1.h index b263662f7e6..790a57bf704 100644 --- a/Algebraic_kernel_d/include/CGAL/RS/functors_1.h +++ b/Algebraic_kernel_d/include/CGAL/RS/functors_1.h @@ -61,7 +61,7 @@ struct Construct_algebraic_real_1{ template struct Compute_polynomial_1: -public CGAL::unary_function{ +public CGAL::cpp98::unary_function{ typedef Polynomial_ Polynomial; typedef Algebraic_ Algebraic; Polynomial operator()(const Algebraic &x)const{ @@ -71,7 +71,7 @@ public CGAL::unary_function{ template struct Is_coprime_1: -public CGAL::binary_function{ +public CGAL::cpp98::binary_function{ typedef Polynomial_ Polynomial; typedef Ptraits_ Ptraits; typedef typename Ptraits::Gcd_up_to_constant_factor Gcd; @@ -257,7 +257,7 @@ template class Sign_at_1: -public CGAL::binary_function{ +public CGAL::cpp98::binary_function{ // This implementation will work with any polynomial type whose // coefficient type is explicit interoperable with Gmpfi. // TODO: Make this function generic. @@ -363,7 +363,7 @@ template class Is_zero_at_1: -public CGAL::binary_function{ +public CGAL::cpp98::binary_function{ // This implementation will work with any polynomial type whose // coefficient type is explicit interoperable with Gmpfi. // TODO: Make this function generic. @@ -443,7 +443,7 @@ public CGAL::binary_function{ // programs assume that this is equal to int template struct Number_of_solutions_1: -public CGAL::unary_function{ +public CGAL::cpp98::unary_function{ typedef Polynomial_ Polynomial_1; typedef Isolator_ Isolator; size_t operator()(const Polynomial_1 &p)const{ @@ -459,7 +459,7 @@ template struct Compare_1: -public CGAL::binary_function{ +public CGAL::cpp98::binary_function{ typedef Algebraic_ Algebraic; typedef Bound_ Bound; typedef Comparator_ Comparator; @@ -511,7 +511,7 @@ template struct Bound_between_1: -public CGAL::binary_function{ +public CGAL::cpp98::binary_function{ typedef Algebraic_ Algebraic; typedef Bound_ Bound; typedef Comparator_ Comparator; @@ -551,7 +551,7 @@ template struct Isolate_1: -public CGAL::binary_function >{ +public CGAL::cpp98::binary_function >{ typedef Polynomial_ Polynomial_1; typedef Bound_ Bound; typedef Algebraic_ Algebraic; @@ -589,7 +589,7 @@ template struct Approximate_absolute_1: -public CGAL::binary_function >{ +public CGAL::cpp98::binary_function >{ typedef Polynomial_ Polynomial_1; typedef Bound_ Bound; typedef Algebraic_ Algebraic; @@ -621,7 +621,7 @@ template struct Approximate_relative_1: -public CGAL::binary_function >{ +public CGAL::cpp98::binary_function >{ typedef Polynomial_ Polynomial_1; typedef Bound_ Bound; typedef Algebraic_ Algebraic; diff --git a/Algebraic_kernel_d/include/CGAL/RS/functors_z_1.h b/Algebraic_kernel_d/include/CGAL/RS/functors_z_1.h index 36c8e4f5ee4..3d03a28f19a 100644 --- a/Algebraic_kernel_d/include/CGAL/RS/functors_z_1.h +++ b/Algebraic_kernel_d/include/CGAL/RS/functors_z_1.h @@ -69,7 +69,7 @@ struct Construct_algebraic_real_z_1{ template struct Compute_polynomial_z_1: -public CGAL::unary_function{ +public CGAL::cpp98::unary_function{ typedef Polynomial_ Polynomial; typedef Algebraic_ Algebraic; Polynomial operator()(const Algebraic &x)const{ @@ -79,7 +79,7 @@ public CGAL::unary_function{ template struct Is_coprime_z_1: -public CGAL::binary_function{ +public CGAL::cpp98::binary_function{ typedef Polynomial_ Polynomial; typedef Ptraits_ Ptraits; typedef typename Ptraits::Gcd_up_to_constant_factor Gcd; @@ -285,7 +285,7 @@ template class Sign_at_z_1: -public CGAL::binary_function{ +public CGAL::cpp98::binary_function{ // This implementation will work with any polynomial type whose // coefficient type is explicit interoperable with Gmpfi. // TODO: Make this function generic. @@ -397,7 +397,7 @@ template class Is_zero_at_z_1: -public CGAL::binary_function{ +public CGAL::cpp98::binary_function{ // This implementation will work with any polynomial type whose // coefficient type is explicit interoperable with Gmpfi. // TODO: Make this function generic. @@ -483,7 +483,7 @@ template struct Number_of_solutions_z_1: -public CGAL::unary_function{ +public CGAL::cpp98::unary_function{ typedef Polynomial_ Polynomial_1; typedef ZPolynomial_ ZPolynomial_1; typedef PolConverter_ PolConverter; @@ -501,7 +501,7 @@ template struct Compare_z_1: -public CGAL::binary_function{ +public CGAL::cpp98::binary_function{ typedef Algebraic_ Algebraic; typedef Bound_ Bound; typedef Comparator_ Comparator; @@ -553,7 +553,7 @@ template struct Bound_between_z_1: -public CGAL::binary_function{ +public CGAL::cpp98::binary_function{ typedef Algebraic_ Algebraic; typedef Bound_ Bound; typedef Comparator_ Comparator; @@ -596,7 +596,7 @@ template struct Isolate_z_1: -public CGAL::binary_function >{ +public CGAL::cpp98::binary_function >{ typedef Polynomial_ Polynomial_1; typedef ZPolynomial_ ZPolynomial_1; typedef PolConverter_ PolConverter; @@ -640,7 +640,7 @@ template struct Approximate_absolute_z_1: -public CGAL::binary_function >{ +public CGAL::cpp98::binary_function >{ typedef Polynomial_ Polynomial_1; typedef Bound_ Bound; typedef Algebraic_ Algebraic; @@ -672,7 +672,7 @@ template struct Approximate_relative_z_1: -public CGAL::binary_function >{ +public CGAL::cpp98::binary_function >{ typedef Polynomial_ Polynomial_1; typedef Bound_ Bound; typedef Algebraic_ Algebraic; diff --git a/Algebraic_kernel_d/include/CGAL/RS/polynomial_converter_1.h b/Algebraic_kernel_d/include/CGAL/RS/polynomial_converter_1.h index 703c8195755..0d6e7f828fb 100644 --- a/Algebraic_kernel_d/include/CGAL/RS/polynomial_converter_1.h +++ b/Algebraic_kernel_d/include/CGAL/RS/polynomial_converter_1.h @@ -27,7 +27,7 @@ namespace RS_AK1{ template struct Polynomial_converter_1: -public CGAL::unary_function{ +public CGAL::cpp98::unary_function{ typedef InputPolynomial_ InpPolynomial_1; typedef OutputPolynomial_ OutPolynomial_1; OutPolynomial_1 operator()(const InpPolynomial_1&)const; diff --git a/Alpha_shapes_2/include/CGAL/internal/Lazy_alpha_nt_2.h b/Alpha_shapes_2/include/CGAL/internal/Lazy_alpha_nt_2.h index eaafd27f71d..83eeac727d5 100644 --- a/Alpha_shapes_2/include/CGAL/internal/Lazy_alpha_nt_2.h +++ b/Alpha_shapes_2/include/CGAL/internal/Lazy_alpha_nt_2.h @@ -45,7 +45,7 @@ namespace internal { // template < class Input_traits, class Kernel_approx, class Kernel_exact, class Weighted_tag > -class Is_traits_point_convertible +class Is_traits_point_convertible_2 { typedef typename Kernel_traits::Kernel Kernel_input; @@ -60,7 +60,7 @@ public: }; template < class Input_traits, class Kernel_approx, class Kernel_exact > -class Is_traits_point_convertible { typedef typename Kernel_traits::Kernel Kernel_input; @@ -157,7 +157,7 @@ class Lazy_alpha_nt_2 Approx_point to_approx(const Input_point& wp) const { // The traits class' Point_2 must be convertible using the Cartesian converter - CGAL_static_assertion((Is_traits_point_convertible< + CGAL_static_assertion((Is_traits_point_convertible_2< Input_traits, Kernel_approx, Kernel_exact, Weighted_tag>::value)); To_approx converter; @@ -167,7 +167,7 @@ class Lazy_alpha_nt_2 Exact_point to_exact(const Input_point& wp) const { // The traits class' Point_2 must be convertible using the Cartesian converter - CGAL_static_assertion((Is_traits_point_convertible< + CGAL_static_assertion((Is_traits_point_convertible_2< Input_traits, Kernel_approx, Kernel_exact, Weighted_tag>::value)); To_exact converter; diff --git a/Alpha_shapes_3/demo/Alpha_shapes_3/CMakeLists.txt b/Alpha_shapes_3/demo/Alpha_shapes_3/CMakeLists.txt index 3e4a711fc77..e00a76ae742 100644 --- a/Alpha_shapes_3/demo/Alpha_shapes_3/CMakeLists.txt +++ b/Alpha_shapes_3/demo/Alpha_shapes_3/CMakeLists.txt @@ -21,15 +21,11 @@ include(${CGAL_USE_FILE}) find_package(Qt5 QUIET COMPONENTS Xml Script OpenGL Svg) -find_package(QGLViewer) - -if ( CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND ) +if ( CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND ) add_definitions(-DQT_NO_KEYWORDS) # include(${QT_USE_FILE}) - - include_directories (${QGLVIEWER_INCLUDE_DIR}) include_directories (BEFORE ../../include ./ ) # ui file, created wih Qt Designer @@ -43,14 +39,13 @@ if ( CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND ) target_link_libraries( Alpha_shape_3 PRIVATE CGAL::CGAL CGAL::CGAL_Qt5 - Qt5::OpenGL Qt5::Gui - ${QGLVIEWER_LIBRARIES} ) + Qt5::OpenGL Qt5::Gui ) include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake) cgal_add_compilation_test(Alpha_shape_3) else() - message(STATUS "NOTICE: This demo requires CGAL, the QGLViewer, and Qt5, and will not be compiled.") + message(STATUS "NOTICE: This demo requires CGAL, and Qt5, and will not be compiled.") endif() diff --git a/Alpha_shapes_3/demo/Alpha_shapes_3/Viewer.cpp b/Alpha_shapes_3/demo/Alpha_shapes_3/Viewer.cpp index 69d8df641a2..acebba28b5e 100644 --- a/Alpha_shapes_3/demo/Alpha_shapes_3/Viewer.cpp +++ b/Alpha_shapes_3/demo/Alpha_shapes_3/Viewer.cpp @@ -1,11 +1,11 @@ #include "Viewer.h" #include #include -#include +#include #include "CGAL/Qt/CreateOpenGLContext.h" Viewer::Viewer(QWidget* parent) - : QGLViewer(CGAL::Qt::createOpenGLContext(),parent) + : CGAL::QGLViewer(parent) { are_buffers_initialized = false; } @@ -198,7 +198,7 @@ void Viewer::initialize_buffers() } -void Viewer::attrib_buffers(QGLViewer* viewer) +void Viewer::attrib_buffers(CGAL::QGLViewer* viewer) { QMatrix4x4 mvpMatrix; QMatrix4x4 mvMatrix; @@ -261,7 +261,7 @@ void Viewer::attrib_buffers(QGLViewer* viewer) void Viewer::initializeGL() { - QGLViewer::initializeGL(); + CGAL::QGLViewer::initializeGL(); compile_shaders(); } @@ -272,8 +272,8 @@ Viewer::sceneChanged() Iso_cuboid_3 bb = CGAL::bounding_box(scene->points.begin(), scene->points.end()); - this->camera()->setSceneBoundingBox(qglviewer::Vec(bb.xmin(), bb.ymin(), bb.zmin()), - qglviewer::Vec(bb.xmax(), + this->camera()->setSceneBoundingBox(CGAL::qglviewer::Vec(bb.xmin(), bb.ymin(), bb.zmin()), + CGAL::qglviewer::Vec(bb.xmax(), bb.ymax(), bb.zmax())); diff --git a/Alpha_shapes_3/demo/Alpha_shapes_3/Viewer.h b/Alpha_shapes_3/demo/Alpha_shapes_3/Viewer.h index b382b39c9d0..ff19159d837 100644 --- a/Alpha_shapes_3/demo/Alpha_shapes_3/Viewer.h +++ b/Alpha_shapes_3/demo/Alpha_shapes_3/Viewer.h @@ -3,14 +3,14 @@ #include "typedefs.h" #include -#include +#include #include #include #include #include -class Viewer : public QGLViewer, protected QOpenGLFunctions_2_1{ +class Viewer : public CGAL::QGLViewer{ Q_OBJECT CGAL::Timer timer; @@ -61,7 +61,7 @@ private: QOpenGLShaderProgram rendering_program_points; void initialize_buffers(); void compute_elements(); - void attrib_buffers(QGLViewer*); + void attrib_buffers(CGAL::QGLViewer*); void compile_shaders(); public Q_SLOTS: void initializeGL(); diff --git a/Alpha_shapes_3/include/CGAL/internal/Lazy_alpha_nt_3.h b/Alpha_shapes_3/include/CGAL/internal/Lazy_alpha_nt_3.h index 8a4effe1a4b..97005825a79 100644 --- a/Alpha_shapes_3/include/CGAL/internal/Lazy_alpha_nt_3.h +++ b/Alpha_shapes_3/include/CGAL/internal/Lazy_alpha_nt_3.h @@ -45,7 +45,7 @@ namespace internal{ // template < class Input_traits, class Kernel_approx, class Kernel_exact, class Weighted_tag > -class Is_traits_point_convertible +class Is_traits_point_convertible_3 { typedef typename Kernel_traits::Kernel Kernel_input; @@ -60,7 +60,7 @@ public: }; template < class Input_traits, class Kernel_approx, class Kernel_exact > -class Is_traits_point_convertible { typedef typename Kernel_traits::Kernel Kernel_input; @@ -148,7 +148,7 @@ class Lazy_alpha_nt_3{ Approx_point to_approx(const Input_point& wp) const { // The traits class' Point_3 must be convertible using the Cartesian converter - CGAL_static_assertion((Is_traits_point_convertible< + CGAL_static_assertion((Is_traits_point_convertible_3< Input_traits, Kernel_approx, Kernel_exact, Weighted_tag>::value)); To_approx converter; @@ -158,7 +158,7 @@ class Lazy_alpha_nt_3{ Exact_point to_exact(const Input_point& wp) const { // The traits class' Point_3 must be convertible using the Cartesian converter - CGAL_static_assertion((Is_traits_point_convertible< + CGAL_static_assertion((Is_traits_point_convertible_3< Input_traits, Kernel_approx, Kernel_exact, Weighted_tag>::value)); To_exact converter; diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/NewTabDialog.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/NewTabDialog.cpp index 54072193c53..18bff61b342 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/NewTabDialog.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/NewTabDialog.cpp @@ -21,6 +21,7 @@ #include "NewTabDialog.h" #include "ArrangementDemoWindow.h" #include "ui_NewTabDialog.h" +#include NewTabDialog::NewTabDialog( QWidget* parent, Qt::WindowFlags f ) : QDialog( parent, f ), diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_Bezier_curve_traits_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_Bezier_curve_traits_2.h index b52e4299e47..8372ecb4e6c 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_Bezier_curve_traits_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_Bezier_curve_traits_2.h @@ -784,7 +784,7 @@ public: * \return SMALLER if the curve is directed right; * LARGER if the curve is directed left. */ - Comparison_result operator() (const X_monotone_curve_2& cv) + Comparison_result operator() (const X_monotone_curve_2& cv) const { if (cv.is_directed_right()) return (SMALLER); diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_circle_segment_traits_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_circle_segment_traits_2.h index bdbd53d20a4..6a45bafe0c9 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_circle_segment_traits_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_circle_segment_traits_2.h @@ -31,6 +31,7 @@ * The header file for the Arr_circle_segment_traits_2 class. */ +#include #include #include #include @@ -84,7 +85,11 @@ public: /*! Get the next curve index. */ static unsigned int get_index () { - static unsigned int index = 0; +#ifdef CGAL_NO_ATOMIC + static unsigned int index; +#else + static CGAL::cpp11::atomic index; +#endif return (++index); } diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_conic_traits_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_conic_traits_2.h index 69e7e29b755..d84c112662c 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_conic_traits_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_conic_traits_2.h @@ -31,6 +31,7 @@ * The conic traits-class for the arrangement package. */ +#include #include #include #include @@ -114,7 +115,11 @@ public: /*! Get the next conic index. */ static unsigned int get_index () { - static unsigned int index = 0; +#ifdef CGAL_NO_ATOMIC + static unsigned int index; +#else + static CGAL::cpp11::atomic index; +#endif return (++index); } diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Td_active_fictitious_vertex.h b/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Td_active_fictitious_vertex.h index 42abf124819..457d955a7d8 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Td_active_fictitious_vertex.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Td_active_fictitious_vertex.h @@ -16,15 +16,15 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0+ // -// Author(s) : Oren Nechushtan -// updated by: Michal Balas +// Author(s): Oren Nechushtan +// Michal Balas +// Efi Fogel #ifndef CGAL_TD_ACTIVE_FICTITIOUS_VERTEX_H #define CGAL_TD_ACTIVE_FICTITIOUS_VERTEX_H #include - /*! \file * Defintion of the Td_active_fictitious_vertex class. */ @@ -33,7 +33,6 @@ #include #include - #ifdef CGAL_TD_DEBUG #define CGAL_TD_INLINE #else @@ -46,63 +45,61 @@ namespace CGAL { * Implementation of a pseudo-trapezoid as two halfedges(top,bottom) * and two curve-ends(left,right). * Trapezoids are represented as two curve-ends called right and left and - * two halfedges called top and bottom. The curve-ends (points) lie on the - * right and left boundaries of the trapezoid respectively and the halfedges + * two halfedges called top and bottom. The curve-ends (points) lie on the + * right and left boundaries of the trapezoid respectively and the halfedges * bound the trapezoid from above and below. - * There exist degenerate trapezoids called infinite trapezoid; this happens + * There exist degenerate trapezoids called infinite trapezoid; this happens * when one of the four sides is on the parameter space boundary. * Trapezoids are created as active and become inactive when Remove() member * function called. * Each trapezoid has at most four neighbouring trapezoids. - * X_trapezoid structure can represent a real trapezoid, a Td-edge or an + * X_trapezoid structure can represent a real trapezoid, a Td-edge or an * edge-end (end point). */ -template -class Td_active_fictitious_vertex : public Handle -{ +template +class Td_active_fictitious_vertex : public Handle { public: - + //type of traits class - typedef Td_traits_ Traits; - + typedef Td_traits_ Traits; + //type of point (Point_2) - typedef typename Traits::Point Point; + typedef typename Traits::Point Point; //type of X_monotone_curve_2 - typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; + typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; //type of Curve_end - typedef typename Traits::Curve_end Curve_end; - + typedef typename Traits::Curve_end Curve_end; + //type of Halfedge_const_handle (trapezoid edge) - typedef typename Traits::Halfedge_const_handle Halfedge_const_handle; - + typedef typename Traits::Halfedge_const_handle Halfedge_const_handle; + //type of Vertex_const_handle (trapezoid vertex) - typedef typename Traits::Vertex_const_handle Vertex_const_handle; + typedef typename Traits::Vertex_const_handle Vertex_const_handle; //type of Halfedge_around_vertex_const_circulator - typedef typename Traits::Halfedge_around_vertex_const_circulator + typedef typename Traits::Halfedge_around_vertex_const_circulator Halfedge_around_vertex_const_circulator; //type of Td_active_fictitious_vertex (Self) - typedef typename Traits::Td_active_fictitious_vertex Self; - - typedef typename Traits::Td_map_item Td_map_item; + typedef typename Traits::Td_active_fictitious_vertex Self; + + typedef typename Traits::Td_map_item Td_map_item; //type of Trapezoidal decomposition - typedef Trapezoidal_decomposition_2 TD; - + typedef Trapezoidal_decomposition_2 TD; + //type of In face iterator - typedef typename TD::In_face_iterator In_face_iterator; + typedef typename TD::In_face_iterator In_face_iterator; //type of Trapezoidal map search structure - typedef typename TD::Dag_node Dag_node; - + typedef typename TD::Dag_node Dag_node; //friend class declarations: friend class Trapezoidal_decomposition_2; - + #ifdef CGAL_PM_FRIEND_CLASS #if defined(__SUNPRO_CC) || defined(__PGI) || defined(__INTEL_COMPILER) friend class Trapezoidal_decomposition_2::In_face_iterator; @@ -113,199 +110,146 @@ public: #else friend class Trapezoidal_decomposition_2::In_face_iterator; #endif - + #else friend class In_face_iterator; #endif #endif - + /*! \class - * Inner class Data derived from Rep class - */ - class Data : public Rep - { + * Inner class Data derived from Rep class + */ + class Data : public Rep { friend class Td_active_fictitious_vertex; public: //c'tors - Data (Vertex_const_handle _v, - Halfedge_const_handle _cw_he, - Dag_node* _p_node) - : v(_v),cw_he(_cw_he),p_node(_p_node) - { } - - ~Data() { } + Data(Vertex_const_handle _v, Halfedge_const_handle _cw_he, + Dag_node* _p_node) : + v(_v), cw_he(_cw_he), p_node(_p_node) + {} + + ~Data() {} protected: - Vertex_const_handle v; + Vertex_const_handle v; Halfedge_const_handle cw_he; //holds the first edge going cw starting at 12 o'clock Dag_node* p_node; }; - - private: - - Data* ptr() const { return (Data*)(PTR); } - + +private: + Data* ptr() const { return (Data*)(PTR); } + Curve_end vtx_to_ce(Vertex_const_handle v) const { //the circulator is of incoming halfedges - Halfedge_around_vertex_const_circulator he = v->incident_halfedges(); + Halfedge_around_vertex_const_circulator he = v->incident_halfedges(); //if the vertex is associated with a point on the bounded coords, // we can take any incident halfedge. o/w if the vertex lies at infinity, // it has 2 fictitious incident halfedges if (v->is_at_open_boundary() && he->source()->is_at_open_boundary()) ++he; if (v->is_at_open_boundary() && he->source()->is_at_open_boundary()) ++he; - return Curve_end(he->curve(), - (he->direction() == ARR_RIGHT_TO_LEFT)? - ARR_MIN_END : ARR_MAX_END); + return Curve_end(he->curve(), ((he->direction() == ARR_RIGHT_TO_LEFT) ? + ARR_MIN_END : ARR_MAX_END)); } - + #ifndef CGAL_TD_DEBUG #ifdef CGAL_PM_FRIEND_CLASS - protected: +protected: #else - public: // workaround +public: // workaround #endif #else //CGAL_TD_DEBUG - public: +public: #endif //CGAL_TD_DEBUG - /*! Set the DAG node. */ - inline void set_dag_node(Dag_node* p) - { - ptr()->p_node = p; - } - + inline void set_dag_node(Dag_node* p) { ptr()->p_node = p; } + /*! Set the vertex handle (Vertex_const_handle). */ - inline void set_vertex(Vertex_const_handle v) + inline void set_vertex(Vertex_const_handle v) { ptr()->v = v; } + + /*! Set the first he going clockwise starting at 12 o'clock. + */ + inline void set_cw_he(Halfedge_const_handle he) { - ptr()->v = v; - } - - /*! Set the first he going clockwise starting at 12 o'clock (Halfedge_const_handle). */ - inline void set_cw_he(Halfedge_const_handle he) - { - if (cw_he() != Traits::empty_he_handle() && - cw_he()->direction() != he->direction()) - { - ptr()->cw_he = he->twin(); - } - else - { - ptr()->cw_he = he; - } + ptr()->cw_he = ((cw_he() != Traits::empty_he_handle()) && + (cw_he()->direction() != he->direction())) ? + he->twin() : he; } - - public: - + /*! Reset the first he going clockwise starting at 12 o'clock. + */ + inline void reset_cw_he() { ptr()->cw_he = Traits::empty_he_handle(); } + +public: /// \name Constructors. //@{ - Td_active_fictitious_vertex () + Td_active_fictitious_vertex() { - PTR = new Data - (Traits::empty_vtx_handle(), Traits::empty_he_handle(), NULL); + PTR = new Data(Traits::empty_vtx_handle(), Traits::empty_he_handle(), NULL); } - + /*! Constructor given Vertex & Halfedge handles. */ - Td_active_fictitious_vertex (Vertex_const_handle v, - Halfedge_const_handle cw_he, - Dag_node* node = 0) - - - { - PTR = new Data(v, cw_he, node); - } - - + Td_active_fictitious_vertex(Vertex_const_handle v, + Halfedge_const_handle cw_he, + Dag_node* node = 0) + { PTR = new Data(v, cw_he, node); } + + /*! Copy constructor. */ - Td_active_fictitious_vertex (const Self& tr) : Handle(tr) - { - } - + Td_active_fictitious_vertex (const Self& tr) : Handle(tr) {} + //@} - + /// \name Operator overloading. //@{ - /*! Assignment operator. - * operator= should not copy m_dag_node (or otherwise update + /*! Assignment operator. + * operator= should not copy m_dag_node (or otherwise update * Dag_node::replace) */ - inline Self& operator= (const Self& t2) + inline Self& operator=(const Self& t2) { - Handle::operator=(t2); - return *this; + Handle::operator=(t2); + return *this; } /*! Operator==. */ - inline bool operator== (const Self& t2) const - { - return (ptr() == t2.ptr()); - } + inline bool operator==(const Self& t2) const { return (ptr() == t2.ptr()); } /*! Operator!=. */ - inline bool operator!= (const Self& t2) const - { - return !(operator==(t2)); - } + inline bool operator!=(const Self& t2) const { return !(operator==(t2)); } //@} - /// \name Access methods. //@{ - inline Self& self() - { - return *this; - } - - inline const Self& self() const - { - return *this; - } + inline Self& self() { return *this; } + + inline const Self& self() const { return *this; } /*! Access the trapezoid id (PTR). */ - inline unsigned long id() const - { - return (unsigned long) PTR; - } + inline unsigned long id() const { return (unsigned long) PTR; } - /*! Access trapezoid left. - * filters out the infinite case which returns predefined dummy values - */ - inline Vertex_const_handle vertex() const - { - return ptr()->v; - } + /*! Access trapezoid left. + * filters out the infinite case which returns predefined dummy values + */ + inline Vertex_const_handle vertex() const { return ptr()->v; } - Curve_end curve_end() const - { - return vtx_to_ce(vertex()); - } + Curve_end curve_end() const { return vtx_to_ce(vertex()); } + + /*! Access the first he starting at 12 o'clock clockwise. + */ + inline Halfedge_const_handle cw_he() const { return ptr()->cw_he; } - /*! Access the first he starting at 12 o'clock clockwise. - */ - inline Halfedge_const_handle cw_he () const - { - return ptr()->cw_he; - } - - /*! 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;} + //@} - - - - - }; } //namespace CGAL diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Td_active_vertex.h b/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Td_active_vertex.h index 73d86b494e3..d912cf09daa 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Td_active_vertex.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Td_active_vertex.h @@ -16,15 +16,15 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0+ // -// Author(s) : Oren Nechushtan -// updated by: Michal Balas +// Author(s): Oren Nechushtan +// Michal Balas +// Efi Fogel #ifndef CGAL_TD_ACTIVE_VERTEX_H #define CGAL_TD_ACTIVE_VERTEX_H #include - /*! \file * Defintion of the Td_active_vertex class. */ @@ -46,63 +46,62 @@ namespace CGAL { * Implementation of a pseudo-trapezoid as two halfedges(top,bottom) * and two curve-ends(left,right). * Trapezoids are represented as two curve-ends called right and left and - * two halfedges called top and bottom. The curve-ends (points) lie on the - * right and left boundaries of the trapezoid respectively and the halfedges + * two halfedges called top and bottom. The curve-ends (points) lie on the + * right and left boundaries of the trapezoid respectively and the halfedges * bound the trapezoid from above and below. - * There exist degenerate trapezoids called infinite trapezoid; this happens + * There exist degenerate trapezoids called infinite trapezoid; this happens * when one of the four sides is on the parameter space boundary. * Trapezoids are created as active and become inactive when Remove() member * function called. * Each trapezoid has at most four neighbouring trapezoids. - * X_trapezoid structure can represent a real trapezoid, a Td-edge or an + * X_trapezoid structure can represent a real trapezoid, a Td-edge or an * edge-end (end point). */ -template -class Td_active_vertex : public Handle -{ - public: - +template +class Td_active_vertex : public Handle { +public: + //type of traits class - typedef Td_traits_ Traits; - + typedef Td_traits_ Traits; + //type of point (Point_2) - typedef typename Traits::Point Point; + typedef typename Traits::Point Point; //type of X_monotone_curve_2 - typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; + typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2; //type of Curve_end - typedef typename Traits::Curve_end Curve_end; + typedef typename Traits::Curve_end Curve_end; //type of Halfedge_const_handle (trapezoid edge) - typedef typename Traits::Halfedge_const_handle Halfedge_const_handle; - + typedef typename Traits::Halfedge_const_handle Halfedge_const_handle; + //type of Vertex_const_handle (trapezoid vertex) - typedef typename Traits::Vertex_const_handle Vertex_const_handle; + typedef typename Traits::Vertex_const_handle Vertex_const_handle; //type of Halfedge_around_vertex_const_circulator - typedef typename Traits::Halfedge_around_vertex_const_circulator + typedef typename Traits::Halfedge_around_vertex_const_circulator Halfedge_around_vertex_const_circulator; //type of Td_active_vertex (Self) - typedef typename Traits::Td_active_vertex Self; - - typedef typename Traits::Td_map_item Td_map_item; + typedef typename Traits::Td_active_vertex Self; + + typedef typename Traits::Td_map_item Td_map_item; //type of Trapezoidal decomposition - typedef Trapezoidal_decomposition_2 TD; - + typedef Trapezoidal_decomposition_2 TD; + //type of In face iterator - typedef typename TD::In_face_iterator In_face_iterator; + typedef typename TD::In_face_iterator In_face_iterator; //type of Trapezoidal map search structure - typedef typename TD::Dag_node Dag_node; + typedef typename TD::Dag_node Dag_node; //friend class declarations: friend class Trapezoidal_decomposition_2; - + #ifdef CGAL_PM_FRIEND_CLASS #if defined(__SUNPRO_CC) || defined(__PGI) || defined(__INTEL_COMPILER) friend class Trapezoidal_decomposition_2::In_face_iterator; @@ -113,201 +112,145 @@ class Td_active_vertex : public Handle #else friend class Trapezoidal_decomposition_2::In_face_iterator; #endif - + #else friend class In_face_iterator; #endif #endif - + /*! \class - * Inner class Data derived from Rep class - */ - class Data : public Rep - { + * Inner class Data derived from Rep class + */ + class Data : public Rep { friend class Td_active_vertex; public: //c'tors - Data (Vertex_const_handle _v, - Halfedge_const_handle _cw_he, - Dag_node* _p_node) - : v(_v),cw_he(_cw_he),p_node(_p_node) - { } - - ~Data() { } + Data(Vertex_const_handle _v, Halfedge_const_handle _cw_he, + Dag_node* _p_node) : + v(_v), cw_he(_cw_he), p_node(_p_node) + {} + + ~Data() {} protected: - Vertex_const_handle v; + Vertex_const_handle v; Halfedge_const_handle cw_he; //holds the first edge going cw starting at 12 o'clock - Dag_node* p_node; + Dag_node* p_node; }; - - private: - - Data* ptr() const { return (Data*)(PTR); } + +private: + Data* ptr() const { return (Data*)(PTR); } Curve_end vtx_to_ce(Vertex_const_handle v) const { //the circulator is of incoming halfedges - Halfedge_around_vertex_const_circulator he = v->incident_halfedges(); + Halfedge_around_vertex_const_circulator he = v->incident_halfedges(); //if the vertex is associated with a point on the bounded coords, // we can take any incident halfedge. o/w if the vertex lies at infinity, // it has 2 fictitious incident halfedges if (v->is_at_open_boundary() && he->source()->is_at_open_boundary()) ++he; if (v->is_at_open_boundary() && he->source()->is_at_open_boundary()) ++he; - return Curve_end(he->curve(), - (he->direction() == ARR_RIGHT_TO_LEFT)? - ARR_MIN_END : ARR_MAX_END); + return Curve_end(he->curve(), ((he->direction() == ARR_RIGHT_TO_LEFT) ? + ARR_MIN_END : ARR_MAX_END)); } - - + #ifndef CGAL_TD_DEBUG #ifdef CGAL_PM_FRIEND_CLASS - protected: +protected: #else - public: // workaround +public: // workaround #endif #else //CGAL_TD_DEBUG - public: +public: #endif //CGAL_TD_DEBUG - - - + /*! Set the DAG node. */ - inline void set_dag_node(Dag_node* p) - { - ptr()->p_node = p; - } - + inline void set_dag_node(Dag_node* p) { ptr()->p_node = p; } + /*! Set the vertex handle (Vertex_const_handle). */ - inline void set_vertex(Vertex_const_handle v) + inline void set_vertex(Vertex_const_handle v) { ptr()->v = v; } + + /*! Set the first he going clockwise starting at 12 o'clock. + */ + inline void set_cw_he(Halfedge_const_handle he) { - ptr()->v = v; + ptr()->cw_he = ((cw_he() != Traits::empty_he_handle()) && + (cw_he()->direction() != he->direction())) ? + he->twin() : he; } - - /*! Set the first he going clockwise starting at 12 o'clock (Halfedge_const_handle). */ - inline void set_cw_he(Halfedge_const_handle he) - { - if (cw_he() != Traits::empty_he_handle() && - cw_he()->direction() != he->direction()) - { - ptr()->cw_he = he->twin(); - } - else - { - ptr()->cw_he = he; - } - } - - - public: - + + /*! Reset the first he going clockwise starting at 12 o'clock. + */ + inline void reset_cw_he() { ptr()->cw_he = Traits::empty_he_handle(); } + +public: /// \name Constructors. //@{ - Td_active_vertex () + Td_active_vertex() { - PTR = new Data - (Traits::empty_vtx_handle(), Traits::empty_he_handle(), NULL); + PTR = new Data(Traits::empty_vtx_handle(), Traits::empty_he_handle(), NULL); } - /*! Constructor given Vertex & Halfedge handles. */ - Td_active_vertex (Vertex_const_handle v, - Halfedge_const_handle cw_he, + Td_active_vertex(Vertex_const_handle v, Halfedge_const_handle cw_he, Dag_node* node = 0) - - { - PTR = new Data (v, cw_he, node); - } - - + + { PTR = new Data(v, cw_he, node); } + + /*! Copy constructor. */ - Td_active_vertex(const Self& tr) : Handle(tr) - { - } - + Td_active_vertex(const Self& tr) : Handle(tr) {} + //@} - + /// \name Operator overloading. //@{ - /*! Assignment operator. - * operator= should not copy m_dag_node (or otherwise update + /*! Assignment operator. + * operator= should not copy m_dag_node (or otherwise update * Dag_node::replace) */ - inline Self& operator= (const Self& t2) + inline Self& operator=(const Self& t2) { - Handle::operator=(t2); - return *this; + Handle::operator=(t2); + return *this; } /*! Operator==. */ - inline bool operator== (const Self& t2) const - { - return (ptr() == t2.ptr()); - } + inline bool operator==(const Self& t2) const { return (ptr() == t2.ptr()); } /*! Operator!=. */ - inline bool operator!= (const Self& t2) const - { - return !(operator==(t2)); - } + inline bool operator!=(const Self& t2) const { return !(operator==(t2)); } //@} - /// \name Access methods. //@{ - inline Self& self() - { - return *this; - } - - inline const Self& self() const - { - return *this; - } + inline Self& self() { return *this; } + + inline const Self& self() const { return *this; } /*! Access the trapezoid id (PTR). */ - inline unsigned long id() const - { - return (unsigned long) PTR; - } + inline unsigned long id() const { return (unsigned long) PTR; } - inline Vertex_const_handle vertex() const - { - return ptr()->v; - } + inline Vertex_const_handle vertex() const { return ptr()->v; } + + Curve_end curve_end() const { return vtx_to_ce(vertex()); } + + inline const Point& point() const { return vertex()->point(); } + + /*! Access the first he starting at 12 o'clock clockwise. + */ + inline Halfedge_const_handle cw_he() const { return ptr()->cw_he; } - Curve_end curve_end() const - { - return vtx_to_ce(vertex()); - } - - inline const Point& point() const - { - return vertex()->point(); - } - - /*! Access the first he starting at 12 o'clock clockwise. - */ - inline Halfedge_const_handle cw_he () const - { - return ptr()->cw_he; - } - /*! Access DAG node. */ - Dag_node* dag_node() const {return ptr()->p_node; } - - - //@} - - - + Dag_node* dag_node() const { return ptr()->p_node; } + //@} }; } //namespace CGAL diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Td_predicates.h b/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Td_predicates.h index cd352a7a8b6..feb331998fe 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Td_predicates.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Td_predicates.h @@ -35,7 +35,7 @@ template < class Td_traits> class Trapezoidal_decomposition_2; ////MICHAL: not in use //template -//struct Td_active_map_item : public CGAL::unary_function +//struct Td_active_map_item : public CGAL::cpp98::unary_function //{ // bool operator()(const map_item& item) const // { @@ -46,7 +46,7 @@ template < class Td_traits> class Trapezoidal_decomposition_2; ////MICHAL: not in use //template //struct Td_active_non_degenerate_trapezoid : -//public CGAL::unary_function +//public CGAL::cpp98::unary_function //{ // Td_active_non_degenerate_trapezoid(Traits& t) : traits(t) {} // bool operator()(const X_trapezoid& tr) const @@ -59,7 +59,7 @@ template < class Td_traits> class Trapezoidal_decomposition_2; template struct Td_active_edge_item: - public CGAL::unary_function + public CGAL::cpp98::unary_function { Td_active_edge_item(const Traits& t) : traits(t) {} bool operator()(const map_item& item) const @@ -71,7 +71,7 @@ struct Td_active_edge_item: }; template -struct Td_map_item_handle_less : public CGAL::binary_function<_Tp, _Tp, bool> +struct Td_map_item_handle_less : public CGAL::cpp98::binary_function<_Tp, _Tp, bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x->id() < __y->id(); } diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Trapezoidal_decomposition_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Trapezoidal_decomposition_2.h index 31838a2a0ed..5a95a74b6fb 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Trapezoidal_decomposition_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Trapezoidal_decomposition_2.h @@ -16,8 +16,9 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0+ // -// Author(s) : Oren Nechushtan -// Iddo Hanniel +// Author(s): Oren Nechushtan +// Iddo Hanniel +// Efi Fogel #ifndef CGAL_TRAPEZOIDAL_DECOMPOSITION_2_H #define CGAL_TRAPEZOIDAL_DECOMPOSITION_2_H @@ -617,29 +618,36 @@ public: } }; - class set_cw_he_visitor : public boost::static_visitor - { + /*! A visitor to set the cw halfedge of a vertex node. + */ + class set_cw_he_visitor : public boost::static_visitor { public: - set_cw_he_visitor (Halfedge_const_handle he) : m_cw_he(he) {} + set_cw_he_visitor(Halfedge_const_handle he) : m_cw_he(he) {} + + void operator()(Td_active_vertex& t) const { t.set_cw_he(m_cw_he); } - void operator()(Td_active_vertex& t) const - { - t.set_cw_he(m_cw_he); - } void operator()(Td_active_fictitious_vertex& t) const - { - t.set_cw_he(m_cw_he); - } + { t.set_cw_he(m_cw_he); } + + template + void operator()(T& /*t*/) const { CGAL_assertion(false); } - template < typename T > - void operator()(T& /*t*/) const - { - CGAL_assertion(false); - } private: Halfedge_const_handle m_cw_he; }; + /*! A visitor to reset the cw halfedge of a vertex node. + */ + class reset_cw_he_visitor : public boost::static_visitor { + public: + void operator()(Td_active_vertex& t) const { t.reset_cw_he(); } + + void operator()(Td_active_fictitious_vertex& t) const { t.reset_cw_he(); } + + template + void operator()(T& /*t*/) const { CGAL_assertion(false); } + }; + class dag_node_visitor : public boost::static_visitor { public: @@ -1151,6 +1159,11 @@ protected: Halfedge_const_handle new_he, Td_map_item& vtx_item); + /*! Update the cw halfedge of an active vertex after a halfedge is removed. + */ + void update_vtx_cw_he_after_remove(Halfedge_const_handle old_he, + Td_map_item& vtx_item); + ////MICHAL: currently not in use since split is implemented as: remove and insert two //void set_trp_params_after_split_halfedge_update(Halfedge_const_handle new_he, // Td_map_item& vtx_item, @@ -1758,22 +1771,20 @@ public: #endif Halfedge_container container; - #ifdef CGAL_TD_DEBUG unsigned long rep = Halfedge_filter(container, &dag_root()); +#else + Halfedge_filter(container, &dag_root()); #endif - clear(); //// initialize container to point to curves in Td_map_item Tree - //if (rep>0) - //{ + //if (rep>0) { // bool o = set_with_guarantees(false); // typename std::vector::iterator // it = container.begin(), // it_end = container.end(); - // while(it!=it_end) - // { + // while (it != it_end) { // insert(*it); // ++it; // } @@ -1787,8 +1798,7 @@ public: #ifdef CGAL_TD_DEBUG CGAL_assertion(is_valid()); unsigned long sz = number_of_curves(); - if (sz != rep) - { + if (sz != rep) { std::cerr << "\nnumber_of_curves()=" << sz; std::cerr << "\nrepresentatives.size()=" << rep; CGAL_assertion(number_of_curves() == rep); @@ -1832,46 +1842,37 @@ public: // return container.size(); //} + /* Return a container for all active curves. + */ template unsigned long Halfedge_filter(Halfedge_container& container, const Dag_node* ds) const - /* Return a container for all active curves */ { unsigned long sz = number_of_curves(); std::list representatives; - //X_trapezoid_list representatives; ds->filter(representatives, Td_active_edge_item(*traits)); #ifndef CGAL_TD_DEBUG - - CGAL_warning(sz==representatives.size()); - + CGAL_warning(sz == representatives.size()); #else - unsigned long rep=representatives.size(); - if (sz != rep) - { + unsigned long rep = representatives.size(); + if (sz != rep) { std::cerr << "\nnumber_of_curves()=" << sz; std::cerr << "\nrepresentatives.size()=" << rep; CGAL_assertion(number_of_curves()==representatives.size()); } - #endif - if (sz > 0) - { - typename std::list::iterator it = representatives.begin(), - it_end = representatives.end(); - //typename X_trapezoid_list::iterator it = representatives.begin(), - // it_end = representatives.end(); - while(!(it==it_end)) + if (sz > 0) { + for (typename std::list::iterator it = + representatives.begin(); it != representatives.end(); ++it) { - Td_active_edge e (boost::get(*it)); + Td_active_edge e(boost::get(*it)); container.push_back(e.halfedge()); //it represents an active trapezoid - ++it; } } - if(! container.empty()) { + if (! container.empty()) { CGAL::cpp98::random_shuffle(container.begin(),container.end()); } return sz; @@ -2010,7 +2011,6 @@ public: true, *m_dag_root, *m_dag_root); } - protected: //Trapezoidal Decomposition data members @@ -2138,7 +2138,6 @@ private: #endif - void print_cv_data(const X_monotone_curve_2& cv, std::ostream& out = std::cout) const { @@ -2206,7 +2205,6 @@ private: } } - void print_dag_addresses(const Dag_node& curr) const { diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Trapezoidal_decomposition_2_impl.h b/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Trapezoidal_decomposition_2_impl.h index e4bab72e6b3..b85c6fa5dc5 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Trapezoidal_decomposition_2_impl.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Trapezoidal_decomposition_2_impl.h @@ -16,15 +16,15 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0+ // -// Author(s) : Michal Balas -// based on the methods implemented in Trapezoidal_decomposition.h by Oren Nechushtan +// Author(s): Michal Balas +// Efi Fogel +// based on the methods implemented by Oren Nechushtan #ifndef CGAL_TRAPEZOIDAL_DECOMPOSITION_FUNCTIONS_H #define CGAL_TRAPEZOIDAL_DECOMPOSITION_FUNCTIONS_H #include - /*! \file * Member-function definitions for the Trapezoidal_decomposition_2 * class. @@ -45,25 +45,23 @@ namespace CGAL { // Precondition: // The trapezoid is active and contains v in its closure // -template +template typename Trapezoidal_decomposition_2::Dag_node & -Trapezoidal_decomposition_2 -::split_trapezoid_by_vertex(Dag_node& split_node, - Vertex_const_handle v, - Halfedge_const_handle he) +Trapezoidal_decomposition_2:: +split_trapezoid_by_vertex(Dag_node& split_node, + Vertex_const_handle v, + Halfedge_const_handle he) { CGAL_precondition(!split_node.is_null()); if (split_node.is_null()) return split_node; - - Td_map_item curr_item (split_node.get_data()); + Td_map_item curr_item(split_node.get_data()); CGAL_precondition(traits->is_active(curr_item)); Dag_node left_node, right_node; - if (traits->is_td_trapezoid(curr_item)) - { - Td_active_trapezoid& tr (boost::get(curr_item)); + if (traits->is_td_trapezoid(curr_item)) { + Td_active_trapezoid& tr(boost::get(curr_item)); CGAL_warning(traits->is_in_closure(tr, traits->vtx_to_ce(v))); @@ -73,41 +71,40 @@ Trapezoidal_decomposition_2 right_node.set_data(Td_active_trapezoid (v, tr.right(), tr.bottom(), tr.top())); - Td_active_trapezoid& left_tr (boost::get(left_node.get_data())); - Td_active_trapezoid& right_tr (boost::get(right_node.get_data())); + Td_active_trapezoid& + left_tr(boost::get(left_node.get_data())); + Td_active_trapezoid& + right_tr(boost::get(right_node.get_data())); CGAL_warning(traits->is_trapezoids_top_equal(left_tr,right_tr)); CGAL_warning(traits->is_trapezoids_bottom_equal(left_tr,right_tr)); CGAL_warning(left_tr.is_on_left_boundary() == tr.is_on_left_boundary()); CGAL_warning(right_tr.is_on_right_boundary() == tr.is_on_right_boundary()); - left_tr.init_neighbours(tr.lb(),tr.lt(),right_node.get_data(),right_node.get_data()); - right_tr.init_neighbours(left_node.get_data(),left_node.get_data(),tr.rb(),tr.rt()); - if (!traits->is_empty_item(tr.lb())) - { + left_tr.init_neighbours(tr.lb(), tr.lt(), + right_node.get_data(), right_node.get_data()); + right_tr.init_neighbours(left_node.get_data(), left_node.get_data(), + tr.rb(), tr.rt()); + if (!traits->is_empty_item(tr.lb())) { Td_active_trapezoid& lb(boost::get(tr.lb())); lb.set_rb(left_node.get_data()); } - if (!traits->is_empty_item(tr.lt())) - { + if (!traits->is_empty_item(tr.lt())) { Td_active_trapezoid& lt(boost::get(tr.lt())); lt.set_rt(left_node.get_data()); } - if (!traits->is_empty_item(tr.rb())) - { + if (!traits->is_empty_item(tr.rb())) { Td_active_trapezoid& rb(boost::get(tr.rb())); rb.set_lb(right_node.get_data()); } - if (!traits->is_empty_item(tr.rt())) - { + if (!traits->is_empty_item(tr.rt())) { Td_active_trapezoid& rt(boost::get(tr.rt())); rt.set_lt(right_node.get_data()); } - } - else //if the curr_item is an edge - { - Td_active_edge& e (boost::get(curr_item)); + else { + // the curr_item is an edge + Td_active_edge& e(boost::get(curr_item)); CGAL_warning(traits->is_in_closure(e, traits->vtx_to_ce(v))); @@ -115,75 +112,78 @@ Trapezoidal_decomposition_2 right_node.set_data(Td_active_edge(e.halfedge())); - Td_active_edge& left_e (boost::get(left_node.get_data())); - Td_active_edge& right_e (boost::get(right_node.get_data())); + Td_active_edge& left_e(boost::get(left_node.get_data())); + Td_active_edge& right_e(boost::get(right_node.get_data())); //CGAL_warning(left_e.is_on_left_boundary() == e.is_on_left_boundary()); //CGAL_warning(right_e.is_on_right_boundary() == e.is_on_right_boundary()); - left_e.init_neighbours(boost::none);//left_e.init_neighbours(e.lb(),e.lt(),Td_map_item(),right_node.get_data()); - right_e.init_neighbours(e.next());//right_e.init_neighbours(left_node.get_data(),left_node.get_data(),e.rb(),e.rt()); - + left_e.init_neighbours(boost::none); + //left_e.init_neighbours(e.lb(),e.lt(),Td_map_item(),right_node.get_data()); + right_e.init_neighbours(e.next()); + //right_e.init_neighbours(left_node.get_data(),left_node.get_data(),e.rb(),e.rt()); } // left and right are set to the point itself, // bottom and top are set to the ray shooting resulting curves at this // stage. //need to define the boundaries flag before creating the trapezoid - Td_map_item vtx_item (build_vertex_map_item(v, he, &split_node)); - split_node.replace( vtx_item, left_node, right_node); //nodes depth are updated here - update_largest_leaf_depth( (std::max)(left_node.depth(), right_node.depth()) ); + Td_map_item vtx_item(build_vertex_map_item(v, he, &split_node)); + split_node.replace(vtx_item, left_node, right_node); //nodes depth are updated here + update_largest_leaf_depth((std::max)(left_node.depth(), right_node.depth())); m_number_of_dag_nodes += 2; #ifndef CGAL_NO_TRAPEZOIDAL_DECOMPOSITION_2_OPTIMIZATION - if (last_cv == curr_item) - last_cv = vtx_item; - if (prev_cv == curr_item) - prev_cv = vtx_item; + if (last_cv == curr_item) last_cv = vtx_item; + if (prev_cv == curr_item) prev_cv = vtx_item; #endif const Dag_node* left_ptr = &split_node.left_child(); const Dag_node* right_ptr = &split_node.right_child(); - boost::apply_visitor(set_dag_node_visitor((Dag_node*)left_ptr),left_ptr->get_data()); //(*left_ptr)->set_dag_node((Dag_node*)left_ptr); - boost::apply_visitor(set_dag_node_visitor((Dag_node*)right_ptr),right_ptr->get_data()); //(*right_ptr)->set_dag_node((Dag_node*)right_ptr); + boost::apply_visitor(set_dag_node_visitor((Dag_node*)left_ptr), + left_ptr->get_data()); + //(*left_ptr)->set_dag_node((Dag_node*)left_ptr); + boost::apply_visitor(set_dag_node_visitor((Dag_node*)right_ptr), + right_ptr->get_data()); + //(*right_ptr)->set_dag_node((Dag_node*)right_ptr); //print_dag_addresses(*m_dag_root); return split_node; } -template +template typename Trapezoidal_decomposition_2::Td_map_item -Trapezoidal_decomposition_2 -::build_vertex_map_item(Vertex_const_handle v, - Halfedge_const_handle he, - Dag_node* node) +Trapezoidal_decomposition_2:: +build_vertex_map_item(Vertex_const_handle v, + Halfedge_const_handle he, + Dag_node* node) { Curve_end ce(traits->vtx_to_ce(v)); - if ((traits->parameter_space_in_x_2_object()(ce.cv(), ce.ce()) == ARR_INTERIOR) - && (traits->parameter_space_in_y_2_object()(ce.cv(), ce.ce()) == ARR_INTERIOR)) + if ((traits->parameter_space_in_x_2_object()(ce.cv(), ce.ce()) == + ARR_INTERIOR) && + (traits->parameter_space_in_y_2_object()(ce.cv(), ce.ce()) == + ARR_INTERIOR)) { - Td_active_vertex vtx (v, he, node); + Td_active_vertex vtx(v, he, node); return vtx; } - else - { - Td_active_fictitious_vertex vtx (v, he, node); + else { + Td_active_fictitious_vertex vtx(v, he, node); return vtx; } } - //----------------------------------------------------------------------------- // Description: // the opposite operation for spliting the trapezoid with // vertical line through ce // Precondition: // tr_node data is a td vertex and is active -template -void Trapezoidal_decomposition_2 -::undo_split_trapezoid_by_vertex(Dag_node& tr_node, const Curve_end& ce) +template +void Trapezoidal_decomposition_2:: +undo_split_trapezoid_by_vertex(Dag_node& tr_node, const Curve_end& ce) { CGAL_precondition(!tr_node.is_null()); Td_map_item item = tr_node.get_data(); @@ -200,7 +200,8 @@ void Trapezoidal_decomposition_2 search_using_dag(tr_right_node, traits, ce, m_empty_he_handle); //make sure the trapezoids are active before merging them - //CGAL_assertion(traits->is_active(tr_left_node.get_data()) && traits->is_active(tr_right_node.get_data())); + //CGAL_assertion(traits->is_active(tr_left_node.get_data()) && + // traits->is_active(tr_right_node.get_data())); // bool mrg_res = merge_if_possible(tr_left_node.get_data(), tr_right_node.get_data()); @@ -209,49 +210,51 @@ void Trapezoidal_decomposition_2 CGAL_warning(!tr_right_node.is_inner_node()); - deactivate_trapezoid( tr_right_node, &tr_left_node); //tr_right_node->remove(&tr_left_node); - update_largest_leaf_depth( tr_left_node.depth()); //tr_left_node is not an inner node + deactivate_trapezoid( tr_right_node, &tr_left_node); + //tr_right_node->remove(&tr_left_node); + update_largest_leaf_depth( tr_left_node.depth()); + //tr_left_node is not an inner node // mark root as deleted deactivate_vertex(tr_node); //tr_node->remove(); - //no need to update m_number_of_dag_nodes because the number of nodes did not change. + // no need to update m_number_of_dag_nodes because the number of nodes does + // not change. // removed nodes were only marked as removed } - -template -void Trapezoidal_decomposition_2 -::deactivate_trapezoid (Dag_node& trpz_node, Dag_node* active_node) const +template +void Trapezoidal_decomposition_2:: +deactivate_trapezoid(Dag_node& trpz_node, Dag_node* active_node) const { CGAL_precondition(traits->is_active(trpz_node.get_data())); CGAL_precondition(traits->is_td_trapezoid(trpz_node.get_data())); - if ( Td_active_trapezoid* trap = boost::get(&trpz_node.get_data()) ) + if (Td_active_trapezoid* trap = + boost::get(&trpz_node.get_data())) trap->clear_neighbors(); 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); } -template -void Trapezoidal_decomposition_2 -::deactivate_vertex (Dag_node& vtx_node) const +template +void Trapezoidal_decomposition_2:: +deactivate_vertex(Dag_node& vtx_node) const { CGAL_precondition(traits->is_active(vtx_node.get_data())); CGAL_precondition(traits->is_td_vertex(vtx_node.get_data())); - if (traits->is_fictitious_vertex(vtx_node.get_data())) - { - Td_active_fictitious_vertex& v(boost::get(vtx_node.get_data())); + if (traits->is_fictitious_vertex(vtx_node.get_data())) { + Td_active_fictitious_vertex& + v(boost::get(vtx_node.get_data())); vtx_node.set_data(Td_inactive_fictitious_vertex(v.vertex(), &vtx_node)); } - else - { + else { Td_active_vertex& v(boost::get(vtx_node.get_data())); vtx_node.set_data(Td_inactive_vertex(v.vertex(), &vtx_node)); } } -template -void Trapezoidal_decomposition_2 -::deactivate_edge (boost::shared_ptr& cv, Dag_node& edge_node) const +template +void Trapezoidal_decomposition_2:: +deactivate_edge(boost::shared_ptr& cv, + Dag_node& edge_node) const { CGAL_precondition(traits->is_active(edge_node.get_data())); CGAL_precondition(traits->is_td_edge(edge_node.get_data())); @@ -259,8 +262,6 @@ void Trapezoidal_decomposition_2 edge_node.set_data(Td_inactive_edge(cv, &edge_node)); } - - //----------------------------------------------------------------------------- // Description: // splits the trapezoid that corresponds to the root of the @@ -268,21 +269,20 @@ void Trapezoidal_decomposition_2 // Precondition: // The root trapezoid is active // The root trapezoid is devided by he or is equal to it and is vertical. -template +template typename Trapezoidal_decomposition_2::Dag_node & -Trapezoidal_decomposition_2 -::split_trapezoid_by_halfedge(Dag_node& split_node, - Td_map_item& prev_e, - Td_map_item& prev_bottom_tr, - Td_map_item& prev_top_tr, - Halfedge_const_handle he) +Trapezoidal_decomposition_2:: +split_trapezoid_by_halfedge(Dag_node& split_node, + Td_map_item& prev_e, + Td_map_item& prev_bottom_tr, + Td_map_item& prev_top_tr, + Halfedge_const_handle he) { - CGAL_warning(traits != NULL); CGAL_precondition(traits->is_active(split_node.get_data())); CGAL_precondition(traits->is_td_trapezoid(split_node.get_data())); - Td_map_item curr_item (split_node.get_data()); + Td_map_item curr_item(split_node.get_data()); Td_active_trapezoid& split_tr = boost::get(curr_item); // sets left and right according to td_edge's source and target positions @@ -291,72 +291,67 @@ Trapezoidal_decomposition_2 // type (TD_EDGE) Td_active_edge sep(he, &split_node); - //creates a one-way path for all the td edges //that represent the Halfedge. //rb() is used to retrieve the //next on path information - Dag_node top_node(Td_active_trapezoid - (split_tr.left(), split_tr.right(), he, split_tr.top())); + Dag_node top_node(Td_active_trapezoid(split_tr.left(), split_tr.right(), he, + split_tr.top())); //Td_active_trapezoid::TD_TRAPEZOID, //split_tr.on_boundaries_flag() & // (CGAL_TD_ON_LEFT_BOUNDARY | // CGAL_TD_ON_RIGHT_BOUNDARY | // CGAL_TD_ON_TOP_BOUNDARY ))); - Dag_node bottom_node(Td_active_trapezoid - (split_tr.left(),split_tr.right(), split_tr.bottom(), he)); + Dag_node bottom_node(Td_active_trapezoid(split_tr.left(),split_tr.right(), + split_tr.bottom(), he)); //Td_active_trapezoid::TD_TRAPEZOID, //split_tr.on_boundaries_flag() & // (CGAL_TD_ON_LEFT_BOUNDARY | // CGAL_TD_ON_RIGHT_BOUNDARY | // CGAL_TD_ON_BOTTOM_BOUNDARY ))); - Td_active_trapezoid& bottom = boost::get(bottom_node.get_data()); - Td_active_trapezoid& top = boost::get(top_node.get_data()); + Td_active_trapezoid& bottom = + boost::get(bottom_node.get_data()); + Td_active_trapezoid& top = + boost::get(top_node.get_data()); top.init_neighbours(prev_top_tr, split_tr.lt(), boost::none , split_tr.rt()); - bottom.init_neighbours(split_tr.lb(), prev_bottom_tr, split_tr.rb(), boost::none); + bottom.init_neighbours(split_tr.lb(), prev_bottom_tr, split_tr.rb(), + boost::none); - if (!traits->is_empty_item(prev_bottom_tr)) - { - Td_active_trapezoid& prev_btm (boost::get(prev_bottom_tr)); + if (!traits->is_empty_item(prev_bottom_tr)) { + Td_active_trapezoid& + prev_btm(boost::get(prev_bottom_tr)); prev_btm.set_rt(bottom_node.get_data()); } - if (!traits->is_empty_item(prev_top_tr)) - { - Td_active_trapezoid& prev_top (boost::get(prev_top_tr)); + if (!traits->is_empty_item(prev_top_tr)) { + Td_active_trapezoid& prev_top(boost::get(prev_top_tr)); prev_top.set_rb(top_node.get_data()); } - if (!traits->is_empty_item(split_tr.lb())) - { - Td_active_trapezoid& lb (boost::get(split_tr.lb())); + if (!traits->is_empty_item(split_tr.lb())) { + Td_active_trapezoid& lb(boost::get(split_tr.lb())); lb.set_rb(bottom_node.get_data()); } - if (!traits->is_empty_item(split_tr.lt())) - { - Td_active_trapezoid& lt (boost::get(split_tr.lt())); + if (!traits->is_empty_item(split_tr.lt())) { + Td_active_trapezoid& lt(boost::get(split_tr.lt())); lt.set_rt(top_node.get_data()); } - if (!traits->is_empty_item(split_tr.rb())) - { - Td_active_trapezoid& rb (boost::get(split_tr.rb())); + if (!traits->is_empty_item(split_tr.rb())) { + Td_active_trapezoid& rb(boost::get(split_tr.rb())); rb.set_lb(bottom_node.get_data()); } - if (!traits->is_empty_item(split_tr.rt())) - { - Td_active_trapezoid& rt (boost::get(split_tr.rt())); + if (!traits->is_empty_item(split_tr.rt())) { + Td_active_trapezoid& rt(boost::get(split_tr.rt())); rt.set_lt(top_node.get_data()); } split_node.replace(sep,bottom_node,top_node); //nodes depth are updated here - update_largest_leaf_depth( (std::max)(bottom_node.depth(), top_node.depth()) ); + update_largest_leaf_depth((std::max)(bottom_node.depth(), top_node.depth())); m_number_of_dag_nodes += 2; //two new nodes were added to the DAG #ifndef CGAL_NO_TRAPEZOIDAL_DECOMPOSITION_2_OPTIMIZATION - if (last_cv == curr_item) - last_cv = sep; - if (prev_cv == curr_item) - prev_cv = sep; + if (last_cv == curr_item) last_cv = sep; + if (prev_cv == curr_item) prev_cv = sep; #endif const Dag_node* bottomPtr = &split_node.left_child(); @@ -368,22 +363,20 @@ Trapezoidal_decomposition_2 topPtr->get_data()); // Td_active_edge& new_e = boost::get(split_node.get_data()); - if (!traits->is_empty_item(prev_e)) - { - Td_active_edge& e ( boost::get(prev_e)); + if (!traits->is_empty_item(prev_e)) { + Td_active_edge& e( boost::get(prev_e)); e.set_next(split_node.get_data()); } //update these trapezoids pointers. // will be used for the next trapezoid that should be split // by this Halfedge prev_bottom_tr = bottomPtr->get_data(); //(*bottomPtr).operator->(); - prev_top_tr = topPtr->get_data(); //(*topPtr).operator->(); - prev_e = split_node.get_data(); //tt.operator->(); + prev_top_tr = topPtr->get_data(); //(*topPtr).operator->(); + prev_e = split_node.get_data(); //tt.operator->(); return split_node; } - //----------------------------------------------------------------------------- // Description: // update @@ -395,36 +388,37 @@ Trapezoidal_decomposition_2 // starting from this vertex // this point must be an interior point and not a point on the boundaries, // since a point on the boundaries is related to one curve only -template +template typename Trapezoidal_decomposition_2::Td_map_item & -Trapezoidal_decomposition_2 -::update_vtx_with_new_edge(Halfedge_const_handle he, - const Curve_end& ce, - Td_map_item& vtx_item, - const Locate_type& - CGAL_precondition_code(lt)) +Trapezoidal_decomposition_2:: +update_vtx_with_new_edge(Halfedge_const_handle he, + const Curve_end& ce, + Td_map_item& vtx_item, + const Locate_type& + CGAL_precondition_code(lt)) { CGAL_assertion(traits != NULL); CGAL_precondition(lt == POINT); CGAL_precondition(traits->is_active(vtx_item)); //ee is interior - CGAL_assertion((traits->parameter_space_in_x_2_object()(ce.cv(), ce.ce()) - == ARR_INTERIOR) && - (traits->parameter_space_in_y_2_object()(ce.cv(), ce.ce()) - == ARR_INTERIOR) ); + CGAL_assertion((traits->parameter_space_in_x_2_object()(ce.cv(), ce.ce()) == + ARR_INTERIOR) && + (traits->parameter_space_in_y_2_object()(ce.cv(), ce.ce()) == + ARR_INTERIOR) ); //the underlying point of ce const Point& p = (ce.ce() == ARR_MIN_END) ? - traits->construct_min_vertex_2_object()(ce.cv()) : - traits->construct_max_vertex_2_object()(ce.cv()) ; + traits->construct_min_vertex_2_object()(ce.cv()) : + traits->construct_max_vertex_2_object()(ce.cv()) ; //set cw to hold the halfedge whose source is p, // which is clockwise "smallest" starting from top (12 o'clock) - Halfedge_const_handle cw_he (boost::apply_visitor(cw_he_visitor(), vtx_item)); - if (traits->compare_cw_around_point_2_object() - (he->curve(), is_edge_to_right(he,p), - cw_he->curve(), - is_edge_to_right(cw_he,p), p) == SMALLER) + Halfedge_const_handle cw_he(boost::apply_visitor(cw_he_visitor(), vtx_item)); + if (traits->compare_cw_around_point_2_object()(he->curve(), + is_edge_to_right(he,p), + cw_he->curve(), + is_edge_to_right(cw_he,p), + p) == SMALLER) { boost::apply_visitor(set_cw_he_visitor(he),vtx_item);//v_tr->set_top(he); } @@ -434,39 +428,36 @@ Trapezoidal_decomposition_2 //----------------------------------------------------------------------------- // Description: -template +template typename Trapezoidal_decomposition_2::Td_map_item & -Trapezoidal_decomposition_2 -::insert_curve_at_vtx_using_dag (Halfedge_const_handle he, - Vertex_const_handle v, - Td_map_item& item, - const Locate_type& - CGAL_precondition_code(lt)) +Trapezoidal_decomposition_2:: +insert_curve_at_vtx_using_dag(Halfedge_const_handle he, + Vertex_const_handle v, + Td_map_item& item, + const Locate_type& + CGAL_precondition_code(lt)) { CGAL_precondition(lt==TRAPEZOID || lt==UNBOUNDED_TRAPEZOID); Dag_node* node = boost::apply_visitor(dag_node_visitor(), item); CGAL_assertion(node != NULL); - CGAL_assertion (he != m_empty_he_handle); + CGAL_assertion(he != m_empty_he_handle); //we need to use the halfedge whose source is v. //MICHAL: do we have to? if (he->source() == v) - // if ((ce_pair.second == ARR_MIN_END && he->direction() == ARR_LEFT_TO_RIGHT) || - // (ce_pair.second == ARR_MAX_END && he->direction() == ARR_RIGHT_TO_LEFT) ) - { + // if ((ce_pair.second == ARR_MIN_END && + // he->direction() == ARR_LEFT_TO_RIGHT) || + // (ce_pair.second == ARR_MAX_END && + // he->direction() == ARR_RIGHT_TO_LEFT) ) return *split_trapezoid_by_vertex(*node, v, he); - } - else - { - return *split_trapezoid_by_vertex(*node, v, he->twin()); - } + else return *split_trapezoid_by_vertex(*node, v, he->twin()); } ////----------------------------------------------------------------------------- //// Description: -//template +//template //void Trapezoidal_decomposition_2 //::set_trp_params_after_halfedge_update(Halfedge_const_handle old_he, // Halfedge_const_handle new_he, @@ -488,28 +479,47 @@ Trapezoidal_decomposition_2 //----------------------------------------------------------------------------- // Description: -template -void Trapezoidal_decomposition_2 -::update_vtx_cw_he_after_merge (const X_monotone_curve_2& old_cv, - Halfedge_const_handle new_he, - Td_map_item& vtx_item) +template +void Trapezoidal_decomposition_2:: +update_vtx_cw_he_after_merge(const X_monotone_curve_2& old_cv, + Halfedge_const_handle new_he, + Td_map_item& vtx_item) { CGAL_precondition(traits->is_td_vertex(vtx_item)); CGAL_precondition(traits->is_active(vtx_item)); - 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)); //make sure the cw_he is added in same direction as before // such that v_tr is the source (done inside the set methods) if (traits->equal_2_object()(cw_he->curve(), old_cv)) - { boost::apply_visitor(set_cw_he_visitor(new_he), vtx_item); +} + +//----------------------------------------------------------------------------- +// Description: +// Update the cw he after a halfedge is removed. +// +template +void Trapezoidal_decomposition_2:: +update_vtx_cw_he_after_remove(Halfedge_const_handle old_he, + Td_map_item& vtx_item) +{ + CGAL_precondition(traits->is_td_vertex(vtx_item)); + CGAL_precondition(traits->is_active(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)) { + Halfedge_const_handle new_he = cw_he->twin()->prev(); + if (new_he != old_he) + boost::apply_visitor(set_cw_he_visitor(new_he), vtx_item); + else boost::apply_visitor(reset_cw_he_visitor(), vtx_item); } } ////MICHAL: currently not in use since split is implemented as removed and insert two //// in case the split is done differenty - this method would have to be rewritten since it is obsolete -//template +//template //void Trapezoidal_decomposition_2 //::set_trp_params_after_split_halfedge_update(Halfedge_const_handle new_he, // Td_map_item& vtx_item, @@ -544,39 +554,36 @@ void Trapezoidal_decomposition_2 // end==0 or end is on the path of the iterator // postcondition: // end is pointer to the last trapezoid encountered,if any -template -void Trapezoidal_decomposition_2 -::update_map_items_after_merge (In_face_iterator& it, - Halfedge_const_handle old_he, - Halfedge_const_handle new_he, - Vertex_const_handle /* min_v */, - Vertex_const_handle /* max_v */, - Td_map_item& end) +template +void Trapezoidal_decomposition_2:: +update_map_items_after_merge(In_face_iterator& it, + Halfedge_const_handle old_he, + Halfedge_const_handle new_he, + Vertex_const_handle /* min_v */, + Vertex_const_handle /* max_v */, + Td_map_item& end) { Td_map_item last_item = Td_map_item(0); - while (!!it && !(*it == end)) - { + while (!!it && !(*it == end)) { Td_map_item curr_item = *it; CGAL_assertion(traits->is_active(curr_item)); - if (traits->is_td_edge(curr_item)) - { + if (traits->is_td_edge(curr_item)) { Td_active_edge& e(boost::get(curr_item)); if (e.halfedge() == old_he || e.halfedge() == old_he->twin()) e.set_halfedge(new_he); } - else if (traits->is_td_trapezoid(curr_item)) - { + else if (traits->is_td_trapezoid(curr_item)) { Td_active_trapezoid& tr(boost::get(curr_item)); if (tr.bottom() == old_he || tr.bottom() == old_he->twin()) tr.set_bottom(new_he); - if (tr.top() == old_he || tr.top() == old_he->twin()) - tr.set_top(new_he); + if (tr.top() == old_he || tr.top() == old_he->twin()) tr.set_top(new_he); } - else //if is_td_vertex - { - Halfedge_const_handle cw_he (boost::apply_visitor(cw_he_visitor(), curr_item)); + else { + //if is_td_vertex + Halfedge_const_handle cw_he(boost::apply_visitor(cw_he_visitor(), + curr_item)); if (cw_he == old_he || cw_he == old_he->twin()) boost::apply_visitor(set_cw_he_visitor(new_he), curr_item); } @@ -599,65 +606,58 @@ void Trapezoidal_decomposition_2 // output is the closest active trapezoid to ce/p_he // remark: // use this function with care! -template +template typename Trapezoidal_decomposition_2::Locate_type -Trapezoidal_decomposition_2 -::search_using_dag (Dag_node& curr_node, - const Traits* traits, - const Point& p, - Halfedge_const_handle he, - Comparison_result up /*=EQUAL*/) const +Trapezoidal_decomposition_2:: +search_using_dag(Dag_node& curr_node, + const Traits* traits, + const Point& p, + Halfedge_const_handle he, + Comparison_result up /*=EQUAL*/) const { - while(true) - { + while (true) { //curr_node is the current pointer to node in the data structure //curr_item is the curent Td_map_item held in curr_node Td_map_item curr_item(curr_node.get_data()); - if (traits->is_td_vertex(curr_item)) - { // if the curr_item represents a vertex + if (traits->is_td_vertex(curr_item)) { + // the curr_item represents a vertex //bool is_fict_vtx = traits->is_fictitious_vertex(curr_item); //if ((is_fict_vtx && is_end_point_left_low(p, *(boost::apply_visitor(curve_end_for_fict_vertex_visitor(),curr_item)))) || // (!is_fict_vtx && is_end_point_left_low(p, boost::apply_visitor(point_for_vertex_visitor(), curr_item))) ) - if (is_end_point_left_low(p, curr_node)) - { + if (is_end_point_left_low(p, curr_node)) { curr_node = curr_node.left_child(); continue; } //else if ((is_fict_vtx && is_end_point_right_top(p, *(boost::apply_visitor(curve_end_for_fict_vertex_visitor(),curr_item)))) || // (!is_fict_vtx && is_end_point_right_top(p, boost::apply_visitor(point_for_vertex_visitor(), curr_item))) ) - else if (is_end_point_right_top(p, curr_node)) - { + else if (is_end_point_right_top(p, curr_node)) { curr_node = curr_node.right_child(); continue; } //else if ((is_fict_vtx && traits->equal_curve_end_2_object()(*(boost::apply_visitor(curve_end_for_fict_vertex_visitor(),curr_item)), p)) || // (!is_fict_vtx && traits->equal_2_object()(boost::apply_visitor(point_for_vertex_visitor(), curr_item), p)) ) - else if (are_equal_end_points(p, curr_node)) - { - if (he == m_empty_he_handle) //if he is the empty handle - { - if ( up == EQUAL ) - { // point found! - if (traits->is_active(curr_item)) - return POINT; + else if (are_equal_end_points(p, curr_node)) { + if (he == m_empty_he_handle) { + // he is the empty handle + if (up == EQUAL) { + // point found! + if (traits->is_active(curr_item)) return POINT; curr_node = curr_node.left_child(); } - else if ( up == LARGER ) { // vertical ray shut up + else if (up == LARGER) { // vertical ray shut up curr_node = curr_node.right_child(); } - else /*if ( up == SMALLER ) */ { - curr_node = curr_node.left_child(); // vertical ray shut down - } + else curr_node = curr_node.left_child(); continue; } - else //if he was given - { - bool is_equal_to_he_min = traits->equal_curve_end_2_object() - (Curve_end(he,ARR_MIN_END), p); - bool is_equal_to_he_max = traits->equal_curve_end_2_object() - (Curve_end(he,ARR_MAX_END), p); + else { + // he was given + bool is_equal_to_he_min = + traits->equal_curve_end_2_object()(Curve_end(he,ARR_MIN_END), p); + bool is_equal_to_he_max = + traits->equal_curve_end_2_object()(Curve_end(he,ARR_MAX_END), p); CGAL_assertion( is_equal_to_he_min || is_equal_to_he_max ); CGAL_USE(is_equal_to_he_max); @@ -666,8 +666,7 @@ Trapezoidal_decomposition_2 continue; } } - else - { + else { CGAL_assertion(is_end_point_left_low(p,curr_node) || is_end_point_right_top(p,curr_node) || are_equal_end_points(p,curr_node)); @@ -684,96 +683,74 @@ Trapezoidal_decomposition_2 return Locate_type(); } } - if (traits->is_td_edge(curr_item)) - { // if curr_item represents an edge, + if (traits->is_td_edge(curr_item)) { + // curr_item represents an edge, // so top() is a real Halfedge with a curve() if curr_item is active // or curr_item holds the curve if it is not active const X_monotone_curve_2& he_cv = *(boost::apply_visitor(cv_for_edge_visitor(), curr_item)); Comparison_result cres = traits->compare_y_at_x_2_object()(p, he_cv); - if (cres == SMALLER) - { + if (cres == SMALLER) { curr_node = curr_node.left_child(); continue; } - else if (cres == LARGER) - { + else if (cres == LARGER) { curr_node = curr_node.right_child(); continue; } - else - { + else { // p is on the curve itself - CGAL_warning( - (cres == EQUAL) && - (traits->compare_curve_end_x_2_object() - (p, Curve_end(he_cv,ARR_MAX_END)) != LARGER) && - (traits->compare_curve_end_x_2_object() - (p, Curve_end(he_cv,ARR_MIN_END)) != SMALLER)); + CGAL_warning((cres == EQUAL) && + (traits->compare_curve_end_x_2_object() + (p, Curve_end(he_cv,ARR_MAX_END)) != LARGER) && + (traits->compare_curve_end_x_2_object() + (p, Curve_end(he_cv,ARR_MIN_END)) != SMALLER)); - if (he == m_empty_he_handle) //if he was not given - { + if (he == m_empty_he_handle) { + //f he was not given // For a vertical curve, we always visit it after visiting // one of its endpoints. - if ((up == EQUAL) || traits->is_vertical(curr_item)) - { - if (traits->is_active(curr_item)) - return CURVE; + if ((up == EQUAL) || traits->is_vertical(curr_item)) { + if (traits->is_active(curr_item)) return CURVE; curr_node = curr_node.left_child(); } - else if (up == LARGER) - { + else if (up == LARGER) { curr_node = curr_node.right_child(); } - else - { // if (up==SMALLER) - curr_node = curr_node.left_child(); - } + else curr_node = curr_node.left_child(); continue; } - else //if he was given - { + else { + // he was given //p is a parameter space interior point - bool is_min_equal = traits->equal_curve_end_2_object() - (Curve_end(he,ARR_MIN_END), - Curve_end(he_cv,ARR_MIN_END)); + bool is_min_equal = + traits->equal_curve_end_2_object()(Curve_end(he,ARR_MIN_END), + Curve_end(he_cv,ARR_MIN_END)); - bool is_max_equal = traits->equal_curve_end_2_object() - (Curve_end(he,ARR_MAX_END), - Curve_end(he_cv,ARR_MAX_END)); + bool is_max_equal = + traits->equal_curve_end_2_object()(Curve_end(he,ARR_MAX_END), + Curve_end(he_cv,ARR_MAX_END)); CGAL_warning (is_min_equal || is_max_equal); CGAL_USE(is_max_equal); - Comparison_result res = - is_min_equal ? + Comparison_result res = is_min_equal ? + traits->compare_cw_around_point_2_object() + (he_cv, is_curve_to_right(he_cv, p), + he->curve(), is_edge_to_right(he, p), p) : traits->compare_cw_around_point_2_object() - (he_cv, is_curve_to_right(he_cv,p), - he->curve(), is_edge_to_right(he,p), p) : - traits->compare_cw_around_point_2_object() - (he->curve(), is_edge_to_right(he,p), - he_cv, is_curve_to_right(he_cv,p), p ,false); + (he->curve(), is_edge_to_right(he, p), + he_cv, is_curve_to_right(he_cv,p), p, false); - switch(res) - { - case LARGER: - curr_node = curr_node.right_child(); - break; - case SMALLER: - curr_node = curr_node.left_child(); - break; + switch(res) { + case LARGER: curr_node = curr_node.right_child(); break; + case SMALLER: curr_node = curr_node.left_child(); break; case EQUAL: - switch(up) - { - case LARGER: - curr_node = curr_node.right_child(); - break; - case SMALLER: - curr_node = curr_node.left_child(); - break; + switch(up) { + case LARGER: curr_node = curr_node.right_child(); break; + case SMALLER: curr_node = curr_node.left_child(); break; case EQUAL: - if (traits->is_active(curr_item)) - return CURVE; + if (traits->is_active(curr_item)) return CURVE; curr_node = curr_node.left_child(); break; } @@ -782,11 +759,9 @@ Trapezoidal_decomposition_2 } } } - else - { + else { // if is_degenerate() == 0, meaning: curr_item is a real trapezoid - if (traits->is_active(curr_item)) - { + if (traits->is_active(curr_item)) { Td_active_trapezoid& tr = boost::get(curr_item); return tr.is_on_boundaries() ? UNBOUNDED_TRAPEZOID : TRAPEZOID; } @@ -796,8 +771,6 @@ Trapezoidal_decomposition_2 } } - - ////----------------------------------------------------------------------------- //// Description: //// advances input Data structure using data structure,input point p and @@ -810,7 +783,7 @@ Trapezoidal_decomposition_2 //// output is the closest active trapezoid to ce/p_he //// remark: //// use this function with care! -//template +//template //void //Trapezoidal_decomposition_2 //::search_and_print_using_dag (std::ostream& out, @@ -1015,19 +988,19 @@ Trapezoidal_decomposition_2 // output is the closest active trapezoid to ce/p_he // remark: // use this function with care! -template +template typename Trapezoidal_decomposition_2::Locate_type -Trapezoidal_decomposition_2 -::search_using_dag (Dag_node& curr_node, - const Traits* traits, - const Curve_end& ce, - Halfedge_const_handle he, - Comparison_result up /*=EQUAL*/) const +Trapezoidal_decomposition_2:: +search_using_dag(Dag_node& curr_node, + const Traits* traits, + const Curve_end& ce, + Halfedge_const_handle he, + Comparison_result up /*=EQUAL*/) const { if (he == m_empty_he_handle) - return search_using_dag_with_cv (curr_node,traits,ce,NULL, up); + return search_using_dag_with_cv(curr_node,traits,ce,NULL, up); else - return search_using_dag_with_cv (curr_node,traits,ce,&he->curve(), up); + return search_using_dag_with_cv(curr_node,traits,ce,&he->curve(), up); } //----------------------------------------------------------------------------- @@ -1042,77 +1015,66 @@ Trapezoidal_decomposition_2 // output is the closest active trapezoid to ce/p_cv // remark: // use this function with care! -template +template typename Trapezoidal_decomposition_2::Locate_type -Trapezoidal_decomposition_2 -::search_using_dag_with_cv (Dag_node& curr_node, - const Traits* traits, - const Curve_end& ce, - const X_monotone_curve_2* p_cv, - Comparison_result up /*=EQUAL*/) const +Trapezoidal_decomposition_2:: +search_using_dag_with_cv(Dag_node& curr_node, + const Traits* traits, + const Curve_end& ce, + const X_monotone_curve_2* p_cv, + Comparison_result up /*=EQUAL*/) const { - while(true) - { + while (true) { //curr_node is the current pointer to node in the data structure //curr_item is the curent Td_map_item held in curr_node Td_map_item curr_item(curr_node.get_data()); - if (traits->is_td_vertex(curr_item)) - { // if the curr_item represents a vertex + if (traits->is_td_vertex(curr_item)) { + // the curr_item represents a vertex //bool is_fict_vtx = traits->is_fictitious_vertex(curr_item); //if ((is_fict_vtx && is_end_point_right_top(*(boost::apply_visitor(curve_end_for_fict_vertex_visitor(),curr_item)), ce)) || // (!is_fict_vtx && is_end_point_right_top(boost::apply_visitor(point_for_vertex_visitor(), curr_item), ce)) ) - if (is_end_point_left_low(ce, curr_node)) - { + if (is_end_point_left_low(ce, curr_node)) { curr_node = curr_node.left_child(); continue; } //else if ((is_fict_vtx && is_end_point_left_low(*(boost::apply_visitor(curve_end_for_fict_vertex_visitor(),curr_item)), ce)) || // (!is_fict_vtx && is_end_point_left_low(boost::apply_visitor(point_for_vertex_visitor(), curr_item), ce)) ) - else if (is_end_point_right_top(ce, curr_node)) - { + else if (is_end_point_right_top(ce, curr_node)) { curr_node = curr_node.right_child(); continue; } //else if ((is_fict_vtx && traits->equal_curve_end_2_object()(*(boost::apply_visitor(curve_end_for_fict_vertex_visitor(),curr_item)), ce)) || // (!is_fict_vtx && traits->equal_curve_end_2_object()(boost::apply_visitor(point_for_vertex_visitor(), curr_item), ce)) ) - else if (are_equal_end_points(ce, curr_node)) - { - if (!p_cv) //if p_cv was not given - { - if ( up == EQUAL ) - { // point found! - if (traits->is_active(curr_item)) - return POINT; + else if (are_equal_end_points(ce, curr_node)) { + if (!p_cv) { + // p_cv was not given + if (up == EQUAL) { + // point found! + if (traits->is_active(curr_item)) return POINT; curr_node = curr_node.left_child(); } - else if ( up == LARGER ) - { // vertical ray shut up - curr_node = curr_node.right_child(); - } - else - { // if ( up == SMALLER ) - curr_node = curr_node.left_child(); // vertical ray shut down - } + else if (up == LARGER) curr_node = curr_node.right_child(); + else curr_node = curr_node.left_child(); continue; } - else //if p_cv was given - { - bool is_equal_to_he_min = traits->equal_curve_end_2_object() - (Curve_end(*p_cv,ARR_MIN_END), ce); - bool is_equal_to_he_max = traits->equal_curve_end_2_object() - (Curve_end(*p_cv,ARR_MAX_END), ce); + else { + // p_cv was given + bool is_equal_to_he_min = + traits->equal_curve_end_2_object()(Curve_end(*p_cv,ARR_MIN_END), ce); + bool is_equal_to_he_max = + traits->equal_curve_end_2_object()(Curve_end(*p_cv,ARR_MAX_END), ce); CGAL_assertion( is_equal_to_he_min || is_equal_to_he_max ); CGAL_USE(is_equal_to_he_max); - curr_node = is_equal_to_he_min ? curr_node.right_child() : curr_node.left_child(); + curr_node = is_equal_to_he_min ? + curr_node.right_child() : curr_node.left_child(); continue; } } - else - { + else { CGAL_assertion(is_end_point_left_low(ce, curr_node) || is_end_point_right_top(ce, curr_node) || are_equal_end_points(ce, curr_node)); @@ -1127,73 +1089,64 @@ Trapezoidal_decomposition_2 return Locate_type(); } } - if (traits->is_td_edge(curr_item)) - { // if curr_item represents an edge, + if (traits->is_td_edge(curr_item)) { + // curr_item represents an edge, // so top() is a real Halfedge with a curve() if curr_item is active // or curr_item holds the curve if it is not active - const X_monotone_curve_2& he_cv = *(boost::apply_visitor(cv_for_edge_visitor(), curr_item)); - Comparison_result cres = traits->compare_curve_end_y_at_x_2_object()(ce, he_cv); - if (cres == SMALLER) - { + const X_monotone_curve_2& he_cv = + *(boost::apply_visitor(cv_for_edge_visitor(), curr_item)); + Comparison_result cres = + traits->compare_curve_end_y_at_x_2_object()(ce, he_cv); + if (cres == SMALLER) { curr_node = curr_node.left_child(); continue; } - else if (cres == LARGER) - { + else if (cres == LARGER) { curr_node = curr_node.right_child(); continue; } - else - { + else { // ce is on the CURVE (he_cv = ce.cv()) itself CGAL_warning( (cres == EQUAL) && (traits->compare_curve_end_x_2_object() - (ce, Curve_end(he_cv,ARR_MAX_END)) != LARGER) && + (ce, Curve_end(he_cv,ARR_MAX_END)) != LARGER) && (traits->compare_curve_end_x_2_object() - (ce, Curve_end(he_cv,ARR_MIN_END)) != SMALLER)); + (ce, Curve_end(he_cv,ARR_MIN_END)) != SMALLER)); - if (!p_cv) //if p_cv was not given - { + if (!p_cv) { + // p_cv was not given // For a vertical curve, we always visit it after visiting // one of its endpoints. - if ((up == EQUAL) || traits->is_vertical(curr_item)) - { - if (traits->is_active(curr_item)) - return CURVE; - curr_node = curr_node.left_child(); - } - else if (up == LARGER) - { - curr_node = curr_node.right_child(); - } - else - { // if (up==SMALLER) + if ((up == EQUAL) || traits->is_vertical(curr_item)) { + if (traits->is_active(curr_item)) return CURVE; curr_node = curr_node.left_child(); } + else if (up == LARGER) curr_node = curr_node.right_child(); + else curr_node = curr_node.left_child(); continue; } - else //if p_cv was given - { + else { + // p_cv was given Comparison_result res = EQUAL; if ((traits->parameter_space_in_x_2_object() - (ce.cv(), ce.ce()) == ARR_INTERIOR) && + (ce.cv(), ce.ce()) == ARR_INTERIOR) && (traits->parameter_space_in_y_2_object() - (ce.cv(), ce.ce()) == ARR_INTERIOR) ) + (ce.cv(), ce.ce()) == ARR_INTERIOR) ) { //if ce is interior then there might be more than one curve // with ce as its endpoint - bool is_min_equal = traits->equal_curve_end_2_object() - (Curve_end(*p_cv,ARR_MIN_END), - Curve_end(he_cv,ARR_MIN_END)); + bool is_min_equal = + traits->equal_curve_end_2_object()(Curve_end(*p_cv,ARR_MIN_END), + Curve_end(he_cv,ARR_MIN_END)); - bool is_max_equal = traits->equal_curve_end_2_object() - (Curve_end(*p_cv,ARR_MAX_END), - Curve_end(he_cv,ARR_MAX_END)); + bool is_max_equal = + traits->equal_curve_end_2_object()(Curve_end(*p_cv,ARR_MAX_END), + Curve_end(he_cv,ARR_MAX_END)); - CGAL_warning (is_min_equal || is_max_equal); + CGAL_warning(is_min_equal || is_max_equal); CGAL_USE(is_max_equal); //the underlying point of ce @@ -1202,34 +1155,23 @@ Trapezoidal_decomposition_2 traits->construct_max_vertex_2_object()(ce.cv()) ; res = is_min_equal ? - traits->compare_cw_around_point_2_object() - (he_cv, is_curve_to_right(he_cv,p), - *p_cv, is_curve_to_right(*p_cv,p), p) : - traits->compare_cw_around_point_2_object() - (*p_cv, is_curve_to_right(*p_cv,p), - he_cv, is_curve_to_right(he_cv,p), p ,false); + traits->compare_cw_around_point_2_object() + (he_cv, is_curve_to_right(he_cv,p), + *p_cv, is_curve_to_right(*p_cv,p), p) : + traits->compare_cw_around_point_2_object() + (*p_cv, is_curve_to_right(*p_cv,p), + he_cv, is_curve_to_right(he_cv,p), p ,false); } - switch(res) - { - case LARGER: - curr_node = curr_node.right_child(); - break; - case SMALLER: - curr_node = curr_node.left_child(); - break; + switch(res) { + case LARGER: curr_node = curr_node.right_child(); break; + case SMALLER: curr_node = curr_node.left_child(); break; case EQUAL: - switch(up) - { - case LARGER: - curr_node = curr_node.right_child(); - break; - case SMALLER: - curr_node = curr_node.left_child(); - break; + switch(up) { + case LARGER: curr_node = curr_node.right_child(); break; + case SMALLER: curr_node = curr_node.left_child(); break; case EQUAL: - if (traits->is_active(curr_item)) - return CURVE; + if (traits->is_active(curr_item)) return CURVE; curr_node = curr_node.left_child(); break; } @@ -1238,11 +1180,9 @@ Trapezoidal_decomposition_2 } } } - else - { + else { // if is_degenerate() == 0, meaning: curr_item is a real trapezoid - if (traits->is_active(curr_item)) - { + if (traits->is_active(curr_item)) { Td_active_trapezoid& tr = boost::get(curr_item); return tr.is_on_boundaries() ? UNBOUNDED_TRAPEZOID : TRAPEZOID; } @@ -1252,11 +1192,6 @@ Trapezoidal_decomposition_2 } } - - - - - //----------------------------------------------------------------------------- // Description: // advances input Data structure using data structure,input point ce and @@ -1269,78 +1204,67 @@ Trapezoidal_decomposition_2 // output is the closest active trapezoid to ce/p_cv // remark: // use this function with care! -template +template typename Trapezoidal_decomposition_2::Locate_type -Trapezoidal_decomposition_2 -::search_using_dag_with_cv (Dag_node& curr_node, - const Traits* traits, - const Point& p, - const X_monotone_curve_2* p_cv, - Comparison_result up /*=EQUAL*/) const +Trapezoidal_decomposition_2:: +search_using_dag_with_cv(Dag_node& curr_node, + const Traits* traits, + const Point& p, + const X_monotone_curve_2* p_cv, + Comparison_result up /*=EQUAL*/) const { - while(true) - { + while (true) { //curr_node is the current pointer to node in the data structure //curr_item is the curent Td_map_item held in curr_node Td_map_item curr_item(curr_node.get_data()); - if (traits->is_td_vertex(curr_item)) - { // if the curr_item represents a vertex + if (traits->is_td_vertex(curr_item)) { + // the curr_item represents a vertex //bool is_fict_vtx = traits->is_fictitious_vertex(curr_item); //if ((is_fict_vtx && is_end_point_right_top(*(boost::apply_visitor(curve_end_for_fict_vertex_visitor(),curr_item)), p)) || // (!is_fict_vtx && is_end_point_right_top(boost::apply_visitor(point_for_vertex_visitor(), curr_item), p)) ) - if (is_end_point_left_low(p, curr_node)) - { + if (is_end_point_left_low(p, curr_node)) { curr_node = curr_node.left_child(); continue; } //else if ((is_fict_vtx && is_end_point_left_low(*(boost::apply_visitor(curve_end_for_fict_vertex_visitor(),curr_item)), p)) || // (!is_fict_vtx && is_end_point_left_low(boost::apply_visitor(point_for_vertex_visitor(), curr_item), p)) ) - else if (is_end_point_right_top(p, curr_node)) - { + else if (is_end_point_right_top(p, curr_node)) { curr_node = curr_node.right_child(); continue; } //else if ((is_fict_vtx && traits->equal_curve_end_2_object()(*(boost::apply_visitor(curve_end_for_fict_vertex_visitor(),curr_item)), p)) || // (!is_fict_vtx && traits->equal_2_object()(boost::apply_visitor(point_for_vertex_visitor(), curr_item), p)) ) - else if (are_equal_end_points(p, curr_node)) - { - if (!p_cv) //if p_cv was not given - { - if ( up == EQUAL ) - { // point found! - if (traits->is_active(curr_item)) - return POINT; + else if (are_equal_end_points(p, curr_node)) { + if (!p_cv) { + // p_cv was not given + if (up == EQUAL) { + // point found! + if (traits->is_active(curr_item)) return POINT; curr_node = curr_node.left_child(); } - else if ( up == LARGER ) - { // vertical ray shut up - curr_node = curr_node.right_child(); - } - else - { // if ( up == SMALLER ) - curr_node = curr_node.left_child(); // vertical ray shut down - } + else if (up == LARGER) curr_node = curr_node.right_child(); + else curr_node = curr_node.left_child(); continue; } - else //if p_cv was given - { - bool is_equal_to_he_min = traits->equal_curve_end_2_object() - (Curve_end(*p_cv,ARR_MIN_END), p); - bool is_equal_to_he_max = traits->equal_curve_end_2_object() - (Curve_end(*p_cv,ARR_MAX_END), p); + else { + // p_cv was given + bool is_equal_to_he_min = + traits->equal_curve_end_2_object()(Curve_end(*p_cv,ARR_MIN_END), p); + bool is_equal_to_he_max = + traits->equal_curve_end_2_object()(Curve_end(*p_cv,ARR_MAX_END), p); CGAL_assertion( is_equal_to_he_min || is_equal_to_he_max ); CGAL_USE(is_equal_to_he_max); - curr_node = is_equal_to_he_min ? curr_node.right_child() : curr_node.left_child(); + curr_node = is_equal_to_he_min ? + curr_node.right_child() : curr_node.left_child(); continue; } } - else - { + else { CGAL_assertion(is_end_point_left_low(p, curr_node) || is_end_point_right_top(p, curr_node) || are_equal_end_points(p, curr_node)); @@ -1355,97 +1279,76 @@ Trapezoidal_decomposition_2 return Locate_type(); } } - if (traits->is_td_edge(curr_item)) - { // if curr_item represents an edge, + if (traits->is_td_edge(curr_item)) { + // curr_item represents an edge, // so top() is a real Halfedge with a curve() if curr_item is active // or curr_item holds the curve if it is not active - const X_monotone_curve_2& he_cv = *(boost::apply_visitor(cv_for_edge_visitor(), curr_item)); + const X_monotone_curve_2& he_cv = + *(boost::apply_visitor(cv_for_edge_visitor(), curr_item)); Comparison_result cres = traits->compare_y_at_x_2_object()(p, he_cv); - if (cres == SMALLER) - { + if (cres == SMALLER) { curr_node = curr_node.left_child(); continue; } - else if (cres == LARGER) - { + else if (cres == LARGER) { curr_node = curr_node.right_child(); continue; } - else - { + else { // p is on the CURVE itself CGAL_warning( (cres == EQUAL) && (traits->compare_curve_end_x_2_object() - (p, Curve_end(he_cv,ARR_MAX_END)) != LARGER) && + (p, Curve_end(he_cv,ARR_MAX_END)) != LARGER) && (traits->compare_curve_end_x_2_object() - (p, Curve_end(he_cv,ARR_MIN_END)) != SMALLER)); + (p, Curve_end(he_cv,ARR_MIN_END)) != SMALLER)); - if (!p_cv) //if p_cv was not given - { + if (!p_cv) { + // p_cv was not given // For a vertical curve, we always visit it after visiting // one of its endpoints. - if ((up == EQUAL) || traits->is_vertical(curr_item)) - { - if (traits->is_active(curr_item)) - return CURVE; - curr_node = curr_node.left_child(); - } - else if (up == LARGER) - { - curr_node = curr_node.right_child(); - } - else - { // if (up==SMALLER) + if ((up == EQUAL) || traits->is_vertical(curr_item)) { + if (traits->is_active(curr_item)) return CURVE; curr_node = curr_node.left_child(); } + else if (up == LARGER) curr_node = curr_node.right_child(); + else curr_node = curr_node.left_child(); continue; } - else //if p_cv was given - { + else { + // p_cv was given Comparison_result res = EQUAL; //p is interior then there might be more than one curve // with p as its endpoint - bool is_min_equal = traits->equal_curve_end_2_object() - (Curve_end(*p_cv,ARR_MIN_END), - Curve_end(he_cv,ARR_MIN_END)); + bool is_min_equal = + traits->equal_curve_end_2_object()(Curve_end(*p_cv,ARR_MIN_END), + Curve_end(he_cv,ARR_MIN_END)); - bool is_max_equal = traits->equal_curve_end_2_object() - (Curve_end(*p_cv,ARR_MAX_END), - Curve_end(he_cv,ARR_MAX_END)); + bool is_max_equal = + traits->equal_curve_end_2_object()(Curve_end(*p_cv,ARR_MAX_END), + Curve_end(he_cv,ARR_MAX_END)); - CGAL_warning (is_min_equal || is_max_equal); + CGAL_warning(is_min_equal || is_max_equal); CGAL_USE(is_max_equal); res = is_min_equal ? - traits->compare_cw_around_point_2_object() - (he_cv, is_curve_to_right(he_cv,p), - *p_cv, is_curve_to_right(*p_cv,p), p) : - traits->compare_cw_around_point_2_object() - (*p_cv, is_curve_to_right(*p_cv,p), - he_cv, is_curve_to_right(he_cv,p), p ,false); + traits->compare_cw_around_point_2_object() + (he_cv, is_curve_to_right(he_cv,p), + *p_cv, is_curve_to_right(*p_cv,p), p) : + traits->compare_cw_around_point_2_object() + (*p_cv, is_curve_to_right(*p_cv,p), + he_cv, is_curve_to_right(he_cv,p), p ,false); - switch(res) - { - case LARGER: - curr_node = curr_node.right_child(); - break; - case SMALLER: - curr_node = curr_node.left_child(); - break; + switch(res) { + case LARGER: curr_node = curr_node.right_child(); break; + case SMALLER: curr_node = curr_node.left_child(); break; case EQUAL: - switch(up) - { - case LARGER: - curr_node = curr_node.right_child(); - break; - case SMALLER: - curr_node = curr_node.left_child(); - break; + switch(up) { + case LARGER: curr_node = curr_node.right_child(); break; + case SMALLER: curr_node = curr_node.left_child(); break; case EQUAL: - if (traits->is_active(curr_item)) - return CURVE; + if (traits->is_active(curr_item)) return CURVE; curr_node = curr_node.left_child(); break; } @@ -1454,11 +1357,9 @@ Trapezoidal_decomposition_2 } } } - else - { - // if is_degenerate() == 0, meaning: curr_item is a real trapezoid - if (traits->is_active(curr_item)) - { + else { + // is_degenerate() == 0, meaning: curr_item is a real trapezoid + if (traits->is_active(curr_item)) { Td_active_trapezoid& tr = boost::get(curr_item); return tr.is_on_boundaries() ? UNBOUNDED_TRAPEZOID : TRAPEZOID; } @@ -1468,81 +1369,78 @@ Trapezoidal_decomposition_2 } } - - - - //----------------------------------------------------------------------------- // Description: // -template +template typename Trapezoidal_decomposition_2::Dag_node -Trapezoidal_decomposition_2 -::container2dag (Nodes_map& ar, int left, int right, - int& num_of_new_nodes) const +Trapezoidal_decomposition_2:: +container2dag(Nodes_map& ar, int left, int right, int& num_of_new_nodes) const { CGAL_warning(traits != NULL); - if (right > left) - { + if (right > left) { int d = (int)std::floor((double(right+left))/2); Dag_node& node(ar.find(d)->second); Td_map_item item(node.get_data()); CGAL_assertion(traits->is_active(item)); CGAL_assertion(traits->is_td_trapezoid(item)); Dag_node& tr_node( ar.find(d)->second); - Td_active_trapezoid& tr( boost::get(tr_node.get_data())); + Td_active_trapezoid& tr(boost::get(tr_node.get_data())); Vertex_const_handle v = tr.right(); Curve_end ce(traits->vtx_to_ce(v)); - bool is_interior = traits->parameter_space_in_x_2_object()(ce.cv(), ce.ce()) - && traits->parameter_space_in_y_2_object()(ce.cv(), ce.ce()); + bool is_interior = + traits->parameter_space_in_x_2_object()(ce.cv(), ce.ce()) && + traits->parameter_space_in_y_2_object()(ce.cv(), ce.ce()); Dag_node curr_node; - Dag_node left_child (container2dag(ar,left,d,num_of_new_nodes)); - Dag_node right_child (container2dag(ar,d+1,right,num_of_new_nodes)); - if (is_interior) - { - curr_node.replace(Td_map_item(Td_active_vertex(v,m_empty_he_handle)),left_child, right_child); + Dag_node left_child(container2dag(ar, left, d, num_of_new_nodes)); + Dag_node right_child(container2dag(ar, d+1, right, num_of_new_nodes)); + if (is_interior) { + curr_node.replace(Td_map_item(Td_active_vertex(v, m_empty_he_handle)), + left_child, right_child); } - else - { - curr_node.replace(Td_map_item(Td_active_fictitious_vertex(v,m_empty_he_handle)),left_child, right_child); + else { + curr_node.replace(Td_map_item(Td_active_fictitious_vertex(v, m_empty_he_handle)), left_child, right_child); } num_of_new_nodes++; - boost::apply_visitor(set_dag_node_visitor((Dag_node*)&(curr_node.left_child())),curr_node.left_child().get_data()); - boost::apply_visitor(set_dag_node_visitor((Dag_node*)&(curr_node.right_child())),curr_node.right_child().get_data()); - boost::apply_visitor(set_dag_node_visitor((Dag_node*)&curr_node),curr_node.get_data()); + boost::apply_visitor(set_dag_node_visitor((Dag_node*)&(curr_node.left_child())), curr_node.left_child().get_data()); + boost::apply_visitor(set_dag_node_visitor((Dag_node*)&(curr_node.right_child())), curr_node.right_child().get_data()); + boost::apply_visitor(set_dag_node_visitor((Dag_node*)&curr_node), + curr_node.get_data()); //curr_node.left_child()->set_dag_node(&curr_node.left_child()); //curr_node.right_child()->set_dag_node(&curr_node.right_child()); //curr_node->set_dag_node(&curr_node);// fake temporary node deactivate_vertex(curr_node); //curr_node->remove(); // mark as deleted - boost::apply_visitor(set_dag_node_visitor((Dag_node*)NULL),curr_node.get_data());//curr_node->set_dag_node(0); + boost::apply_visitor(set_dag_node_visitor((Dag_node*)NULL), + curr_node.get_data());//curr_node->set_dag_node(0); return curr_node; } - else - { + else { return ar.find(left)->second; } } -template -bool Trapezoidal_decomposition_2 -::is_last_edge(Halfedge_const_handle /* he */ , Td_map_item& vtx_item) +template +bool Trapezoidal_decomposition_2:: +is_last_edge(Halfedge_const_handle /* he */ , Td_map_item& vtx_item) { CGAL_precondition(traits->is_td_vertex(vtx_item)); CGAL_precondition(traits->is_active(vtx_item)); - Vertex_const_handle v (boost::apply_visitor(vertex_for_active_vertex_visitor(), vtx_item)); + Vertex_const_handle + v(boost::apply_visitor(vertex_for_active_vertex_visitor(), vtx_item)); - typename Arrangement_on_surface_2::Halfedge_around_vertex_const_circulator first, second; + typename Arrangement_on_surface_2::Halfedge_around_vertex_const_circulator + first, second; first = second = v->incident_halfedges(); ++second; - if (second == first) //if he is the only halfedge around v -> return true - return true; + //if he is the only halfedge around v -> return true + if (second == first) return true; return false; } @@ -1555,22 +1453,22 @@ bool Trapezoidal_decomposition_2 // Given an edge-degenerate trapezoid representing a Halfedge, // all the other trapezoids representing the Halfedge can be extracted // via moving continously to the left and right neighbours. -template +template typename Trapezoidal_decomposition_2::Td_map_item -Trapezoidal_decomposition_2 -::insert(Halfedge_const_handle he) //::insert_in_face_interior(Halfedge_const_handle he) +Trapezoidal_decomposition_2::insert(Halfedge_const_handle he) { //print_cv_data(he->curve()); - if (m_with_guarantees) - update(); + if (m_with_guarantees) update(); // locate the input Halfedge end points in the Td_map_item Dag CGAL_assertion(traits != NULL); //get the two vertices of the halfedge - Vertex_const_handle v1 = (he->direction() == ARR_LEFT_TO_RIGHT) ? he->source() : he->target(); - Vertex_const_handle v2 = (he->direction() == ARR_LEFT_TO_RIGHT) ? he->target() : he->source(); + Vertex_const_handle v1 = + (he->direction() == ARR_LEFT_TO_RIGHT) ? he->source() : he->target(); + Vertex_const_handle v2 = + (he->direction() == ARR_LEFT_TO_RIGHT) ? he->target() : he->source(); //define the Curve end points (curve end = vertex) const Curve_end ce1(he, ARR_MIN_END); //MICHAL: to be removed? @@ -1579,62 +1477,53 @@ Trapezoidal_decomposition_2 // make sure that the two endpoints are not the same point CGAL_precondition(!traits->equal_curve_end_2_object()(ce1, ce2)); - Locate_type lt1,lt2; - - //should hold the trapezoids in which the edge endpoints should be located + Locate_type lt1; Td_map_item item1; - Td_map_item item2; #ifndef CGAL_NO_TRAPEZOIDAL_DECOMPOSITION_2_OPTIMIZATION - - locate_optimization(ce1,item1,lt1); - + locate_optimization(ce1, item1, lt1); #else //location of the left endpoint of the edge we're inserting - item1 = locate(ce1,lt1); - + item1 = locate(ce1, lt1); #endif - //the inserted edge should not cut any existing edge - if (lt1 == CURVE) - { + if (lt1 == CURVE) { CGAL_precondition_msg(lt1 != CURVE, "Input is not planar as\ one of the input point inside previously inserted Halfedge."); return Td_map_item(0); } - //if the edge starts at vertex, we should not insert it into the DAG, - //but we should update all the edges incident to the vertex. - //else if this is a new vertex - insert a node to the DAG that will represent the new vertex. - //the incident edges in this case is only the edge itself, and so it is a trivial operation. + // if the edge starts at a vertex, we should not insert it into the DAG. + // Instead, we should update all the edges incident to the vertex. + // Otherwise, this is a new vertex, insert a node to the DAG that represents + // the new vertex. In this case, the the edge itself is the only incident + // edge, and so it is a trivial operation. Td_map_item p1_item = (lt1 == POINT) ? - update_vtx_with_new_edge(he,ce1,item1,lt1) : - insert_curve_at_vtx_using_dag(he,v1,item1,lt1); + update_vtx_with_new_edge(he, ce1, item1, lt1) : + insert_curve_at_vtx_using_dag(he, v1, item1, lt1); + Locate_type lt2; + Td_map_item item2; #ifndef CGAL_NO_TRAPEZOIDAL_DECOMPOSITION_2_OPTIMIZATION - - locate_optimization(ce2,item2,lt2); + locate_optimization(ce2, item2, lt2); locate_opt_empty(); - #else // TODO(oren): locating the second endpoint. this is not necessary, // and time consuming. - item2 = locate(ce2,lt2); - + item2 = locate(ce2, lt2); #endif - if (lt2==CURVE) - { - CGAL_precondition_msg(lt2!=CURVE,"Input is not planar as\ + if (lt2 == CURVE) { + CGAL_precondition_msg(lt2 != CURVE, "Input is not planar as\ one of the input point inside previously inserted Halfedge."); return Td_map_item(0); } Td_map_item p2_item = (lt2 == POINT) ? - update_vtx_with_new_edge(he,ce2,item2,lt2) : - insert_curve_at_vtx_using_dag(he,v2,item2,lt2); + update_vtx_with_new_edge(he,ce2, item2, lt2) : + insert_curve_at_vtx_using_dag(he, v2, item2, lt2); // locate and insert end points of the input halfedge to the Td_map_item // Dag if needed @@ -1657,8 +1546,7 @@ Trapezoidal_decomposition_2 CGAL_assertion(!traits->is_empty_item(*it) && traits->is_td_trapezoid(*it)); - while(!!it) //this means as long as the iterator is valid - { + while(!!it) { //this means as long as the iterator is valid curr_trp = it.trp(); CGAL_assertion(curr_trp != boost::none); prev_bottom_tr = (*curr_trp).lb(); @@ -1668,9 +1556,8 @@ Trapezoidal_decomposition_2 it++; //this is the logic of the iterator. // the iterator goes to the next trapezoid right-high. node = (*curr_trp).dag_node(); - if(first_time) - { - Halfedge_const_handle top_he ((*curr_trp).top()); + if (first_time) { + Halfedge_const_handle top_he((*curr_trp).top()); if((top_he == he) || (top_he == he->twin())) { CGAL_warning((top_he != he) && (top_he != he->twin())); return Td_map_item(0); @@ -1679,20 +1566,18 @@ Trapezoidal_decomposition_2 first_time = false; CGAL_assertion(node != NULL); - split_trapezoid_by_halfedge (*node, old_e, old_bottom_tr, old_top_tr, he); + split_trapezoid_by_halfedge(*node, old_e, old_bottom_tr, old_top_tr, he); - - - if (node->is_inner_node()) - { + if (node->is_inner_node()) { // merge adjacent trapezoids on input Halfedge's bottom side if possible // make sure we try to merge active trapezoids //node->left_child() is active Td_map_item new_btm_item = node->left_child().get_data(); - CGAL_assertion(traits->is_td_trapezoid(new_btm_item) && traits->is_active(new_btm_item)); - if(merge_if_possible(prev_bottom_tr, new_btm_item)) - { - Dag_node* left_child_node = boost::apply_visitor(dag_node_visitor(),prev_bottom_tr); + CGAL_assertion(traits->is_td_trapezoid(new_btm_item) && + traits->is_active(new_btm_item)); + if (merge_if_possible(prev_bottom_tr, new_btm_item)) { + Dag_node* left_child_node = + boost::apply_visitor(dag_node_visitor(),prev_bottom_tr); node->set_left_child(*left_child_node); old_bottom_tr = prev_bottom_tr; m_number_of_dag_nodes--; //update number of nodes in the DAG after merge @@ -1702,9 +1587,9 @@ Trapezoidal_decomposition_2 // make sure we try to merge active trapezoids //node->right_child() is active Td_map_item new_top_item = node->right_child().get_data(); - CGAL_assertion(traits->is_td_trapezoid(new_top_item) && traits->is_active(new_top_item)); - if(merge_if_possible(prev_top_tr, new_top_item)) - { + CGAL_assertion(traits->is_td_trapezoid(new_top_item) && + traits->is_active(new_top_item)); + if (merge_if_possible(prev_top_tr, new_top_item)) { Dag_node* right_child_node = boost::apply_visitor(dag_node_visitor(), prev_top_tr); node->set_right_child(*right_child_node); @@ -1714,8 +1599,7 @@ Trapezoidal_decomposition_2 // update trapezoid's left/right neighbouring relations //MICHAL: if the assertion below fails then we need to check why CGAL_assertion(!traits->is_td_trapezoid(prev)); - if(traits->is_td_trapezoid(prev)) - { + if (traits->is_td_trapezoid(prev)) { //MICHAL: if we reach here ->then this need to be uncommented // I thought that prev is always a degenerate point //curr_trp->set_lb(prev); @@ -1724,18 +1608,14 @@ Trapezoidal_decomposition_2 //prev->set_rt(curr_trp); } } - else - { + else { #ifdef CGAL_TD_DEBUG - CGAL_assertion((*curr_trp).is_valid(traits)); - #endif break; } - } m_number_of_curves++; @@ -1748,20 +1628,17 @@ Trapezoidal_decomposition_2 return old_e; } - //----------------------------------------------------------------------------- // Description: // // Remark: // Assumes the map to be planar. -template -void Trapezoidal_decomposition_2 -::remove(Halfedge_const_handle he) +template +void Trapezoidal_decomposition_2::remove(Halfedge_const_handle he) { //print_dag_addresses(*m_dag_root); - if (m_with_guarantees) - update(); + if (m_with_guarantees) update(); #ifndef CGAL_NO_TRAPEZOIDAL_DECOMPOSITION_2_OPTIMIZATION locate_opt_empty(); @@ -1770,26 +1647,28 @@ void Trapezoidal_decomposition_2 CGAL_warning(traits != NULL); //calculating leftmost and rightmost curve ends of he - const Curve_end leftmost(he,ARR_MIN_END); - const Curve_end rightmost(he,ARR_MAX_END); + const Curve_end leftmost(he, ARR_MIN_END); + const Curve_end rightmost(he, ARR_MAX_END); //locating leftmost & rightmost curve ends - Locate_type lt1,lt2; - Td_map_item p1_item = locate(leftmost,lt1); - Td_map_item p2_item = locate(rightmost,lt2); + Locate_type lt1, lt2; + Td_map_item p1_item = locate(leftmost, lt1); + Td_map_item p2_item = locate(rightmost, lt2); + + update_vtx_cw_he_after_remove(he, p1_item); + update_vtx_cw_he_after_remove(he, p2_item); //both should be located on a point degenerate trapezoid - CGAL_warning(lt1==POINT && lt2==POINT); + CGAL_warning(lt1 == POINT && lt2 == POINT); - if (lt1!=POINT || lt2!=POINT) - return; + if (lt1 != POINT || lt2 != POINT) return; CGAL_warning(boost::apply_visitor(dag_node_visitor(), p1_item) != NULL); CGAL_warning(boost::apply_visitor(dag_node_visitor(), p2_item) != NULL); //retrieve the Dag_nodes of the two point-degenerate trapezoid - Dag_node& p1_node = *(boost::apply_visitor(dag_node_visitor(), p1_item));//*t1.dag_node(); - Dag_node& p2_node = *(boost::apply_visitor(dag_node_visitor(), p2_item));//*t2.dag_node(); + Dag_node& p1_node = *(boost::apply_visitor(dag_node_visitor(), p1_item)); + Dag_node& p2_node = *(boost::apply_visitor(dag_node_visitor(), p2_item)); //calculate the immediate lower, central and upper neighbourhood of // the curve in the data structure @@ -1807,22 +1686,21 @@ void Trapezoidal_decomposition_2 int last_index[] = {0,0}; int sz = 0; - Td_active_trapezoid& btm_it_tr (btm_it.trp()); - Td_active_trapezoid& top_it_tr (top_it.trp()); + Td_active_trapezoid& btm_it_tr(btm_it.trp()); + Td_active_trapezoid& top_it_tr(top_it.trp()); Vertex_const_handle left_v = btm_it_tr.left(); Vertex_const_handle right_v; Td_map_item last_btm_tr_item = Td_map_item(0); //pointer to the last btm_it tr Td_map_item last_top_tr_item = Td_map_item(0); //pointer to the last top_it tr Td_map_item last_new_tr_item = Td_map_item(0); //last new trpz that was created - Td_map_item old_tr_item = Td_map_item(0); //old trpz on which the new is based - + Td_map_item old_tr_item = Td_map_item(0); //old trpz on which the new is based CGAL_warning((top_it.trp()).left() == left_v); //----------------------------------- //1. remove adjacency at left end point // first_cv_tr is the first trapezoid representing he (type TD_EDGE) - Td_map_item first_edge_fragment_item (*mid_it); + Td_map_item first_edge_fragment_item(*mid_it); //----------------------------------- //2. update the map & the dag with new trapezoids which are merge of the @@ -1832,14 +1710,15 @@ void Trapezoidal_decomposition_2 top_it_tr = top_it.trp(); // decide which of btm_it,top_it to increment - inc_btm = is_end_point_left_low(Curve_end(traits->vtx_to_ce(btm_it_tr.right())), - Curve_end(traits->vtx_to_ce(top_it_tr.right()))); + inc_btm = + is_end_point_left_low(Curve_end(traits->vtx_to_ce(btm_it_tr.right())), + Curve_end(traits->vtx_to_ce(top_it_tr.right()))); // the current iterator that should be incremented In_face_iterator& curr_it = inc_btm ? btm_it : top_it; - Td_active_trapezoid& curr_it_tr (curr_it.trp()); + Td_active_trapezoid& curr_it_tr(curr_it.trp()); // reference to the last curr_it tr - Td_map_item& last_tr_item (inc_btm ? last_btm_tr_item : last_top_tr_item); + Td_map_item& last_tr_item(inc_btm ? last_btm_tr_item : last_top_tr_item); //set the new trpz right end right_v = curr_it_tr.right(); @@ -1862,20 +1741,14 @@ void Trapezoidal_decomposition_2 //new_node->set_dag_node(&new_node); //new_node->set_lb(btm_it->lb()); //new_node->set_lt(top_it->lt()); - if (!traits->is_empty_item(last_new_tr_item)) - { + if (!traits->is_empty_item(last_new_tr_item)) { if (traits->is_trpz_top_equal(last_new_tr_item, new_node.get_data())) - { tr.set_lt(last_new_tr_item); //new_node->set_lt(last_new_tr); - } if (traits->is_trpz_bottom_equal(last_new_tr_item, new_node.get_data())) - { tr.set_lb(last_new_tr_item); //new_node->set_lb(last_new_tr); - } } - if (!traits->is_empty_item(tr.lb())) - { + if (!traits->is_empty_item(tr.lb())) { Td_map_item lb_item = tr.lb(); Td_active_trapezoid& lb_tr(boost::get(lb_item)); lb_tr.set_rb(new_node.get_data()); @@ -1887,7 +1760,8 @@ void Trapezoidal_decomposition_2 lt_tr.set_rt(new_node.get_data()); } - last_new_tr_item = new_node.get_data(); //new_node.operator->(); //get the last new trapezoid created + last_new_tr_item = new_node.get_data(); + //new_node.operator->(); //get the last new trapezoid created //update arguments for next iteration: left_v = right_v; //new left is curr right @@ -1902,40 +1776,44 @@ void Trapezoidal_decomposition_2 //copy neighbouring trapezoids in case top/btm are not the same for the old // trapezoid and the next trapezoid after incrementing the old one if (!btm_it || - (inc_btm && !traits->is_trpz_bottom_equal(old_tr_item,*curr_it))) + (inc_btm && !traits->is_trpz_bottom_equal(old_tr_item, *curr_it))) { - Td_map_item rb (boost::apply_visitor(rb_visitor(),old_tr_item)); - if (!traits->is_empty_item(rb)) - { - boost::apply_visitor(set_lb_visitor(last_new_tr_item),rb); //rb->set_lb(last_new_tr); - boost::apply_visitor(set_rb_visitor(rb),last_new_tr_item); //last_new_tr->set_rb(rb); + Td_map_item rb(boost::apply_visitor(rb_visitor(), old_tr_item)); + if (!traits->is_empty_item(rb)) { + boost::apply_visitor(set_lb_visitor(last_new_tr_item), rb); + //rb->set_lb(last_new_tr); + boost::apply_visitor(set_rb_visitor(rb), last_new_tr_item); + //last_new_tr->set_rb(rb); } } if (!top_it || (!inc_btm && !traits->is_trpz_top_equal(old_tr_item,*curr_it))) { - Td_map_item rt (boost::apply_visitor(rt_visitor(),old_tr_item)); + Td_map_item rt(boost::apply_visitor(rt_visitor(), old_tr_item)); if (!traits->is_empty_item(rt)) { - boost::apply_visitor(set_lt_visitor(last_new_tr_item),rt); //rt->set_lt(last_new_tr); - boost::apply_visitor(set_rt_visitor(rt),last_new_tr_item); //last_new_tr->set_rt(rt); + boost::apply_visitor(set_lt_visitor(last_new_tr_item), rt); + //rt->set_lt(last_new_tr); + boost::apply_visitor(set_rt_visitor(rt), last_new_tr_item); + //last_new_tr->set_rt(rt); } } //set the no longer relevant trapezoids as removed and add the new nodes // as their replacement - Dag_node* last_tr_node (boost::apply_visitor(dag_node_visitor(), last_tr_item)); + Dag_node* last_tr_node(boost::apply_visitor(dag_node_visitor(), + last_tr_item)); - if (prev_inc_btm != inc_btm) - { + if (prev_inc_btm != inc_btm) { int num_of_new_nodes = 0; Dag_node tmp = container2dag (new_array, last_index[inc_btm ? 0 : 1], sz-1, num_of_new_nodes); deactivate_trapezoid( *last_tr_node, &tmp); //last_tr->remove(&tmp); - m_number_of_dag_nodes += num_of_new_nodes; //new vertex nodes (rooted at tmp) were added + m_number_of_dag_nodes += num_of_new_nodes; + //new vertex nodes (rooted at tmp) were added m_number_of_dag_nodes += 1; //new node (tmp) was added last_index[inc_btm ? 0 : 1] = sz; @@ -1943,12 +1821,10 @@ void Trapezoidal_decomposition_2 //tmp is the root of a sub graph. //The largest depth in this sub-graph may be the largest leaf depth update_largest_leaf_depth( tmp.max_depth() ); - } - else - { + else { int num_of_new_nodes = 0; - Dag_node tmp = container2dag (new_array, sz-1, sz-1, num_of_new_nodes); + Dag_node tmp = container2dag(new_array, sz-1, sz-1, num_of_new_nodes); deactivate_trapezoid( *last_tr_node, &tmp); //last_tr->remove(&tmp); m_number_of_dag_nodes += 1; //new node (tmp) was added @@ -1968,7 +1844,7 @@ void Trapezoidal_decomposition_2 // get the iterator (btm_it or top_it) that holds the trapezoid that was // not removed in the last iteration In_face_iterator& it = !prev_inc_btm ? btm_it : top_it; - Td_active_trapezoid& tr (it.trp()); + Td_active_trapezoid& tr(it.trp()); // remove the last trapezoid to remove and set the last new trapezoid // created as its replacement. update the relevant data Td_map_item rb = tr.rb(); @@ -1988,24 +1864,27 @@ void Trapezoidal_decomposition_2 const Dag_node* real = &tr.dag_node()->left_child(); boost::apply_visitor(set_dag_node_visitor((Dag_node*)real),real->get_data()); //(*real)->set_dag_node((Dag_node*)real); - if (!traits->is_empty_item(rb)) - { - boost::apply_visitor(set_rb_visitor(rb),last_new_tr_item); //last_new_tr->set_rb(rb); - boost::apply_visitor(set_lb_visitor(last_new_tr_item),rb); //rb->set_lb(last_new_tr); + if (!traits->is_empty_item(rb)) { + boost::apply_visitor(set_rb_visitor(rb),last_new_tr_item); + //last_new_tr->set_rb(rb); + boost::apply_visitor(set_lb_visitor(last_new_tr_item),rb); + //rb->set_lb(last_new_tr); } - if (!traits->is_empty_item(rt)) - { - boost::apply_visitor(set_rt_visitor(rt),last_new_tr_item); //last_new_tr->set_rt(rt); - boost::apply_visitor(set_lt_visitor(last_new_tr_item),rt); //rt->set_lt(last_new_tr); + if (!traits->is_empty_item(rt)) { + boost::apply_visitor(set_rt_visitor(rt),last_new_tr_item); + //last_new_tr->set_rt(rt); + boost::apply_visitor(set_lt_visitor(last_new_tr_item),rt); + //rt->set_lt(last_new_tr); } //----------------------------------- //3. remove the trapezoids that represent the removed halfedge - boost::shared_ptr removed_cv_ptr (new X_monotone_curve_2(he->curve())); - Base_map_item_iterator last_edge_fragment_it = mid_it;//Base_trapezoid_iterator last_mid = mid_it; + boost::shared_ptr + removed_cv_ptr(new X_monotone_curve_2(he->curve())); + Base_map_item_iterator last_edge_fragment_it = mid_it; + //Base_trapezoid_iterator last_mid = mid_it; Dag_node* e_node = NULL; - while(!!++mid_it) - { + while (!!++mid_it) { e_node = boost::apply_visitor(dag_node_visitor(),*last_edge_fragment_it); deactivate_edge(removed_cv_ptr,*e_node); //last_mid->remove(); last_edge_fragment_it = mid_it; @@ -2022,27 +1901,28 @@ void Trapezoidal_decomposition_2 //5. if the halfedge vertices are now isolated, undo the split trapezoid // by point(vtx) operation if (is_last_edge(he ,p1_item)) - undo_split_trapezoid_by_vertex (p1_node, leftmost); + undo_split_trapezoid_by_vertex(p1_node, leftmost); if (is_last_edge(he ,p2_item)) - undo_split_trapezoid_by_vertex (p2_node, rightmost); + undo_split_trapezoid_by_vertex(p2_node, rightmost); + + locate_opt_empty(); //----------------------------------- //6. reevaluating number of curves m_number_of_curves--; } - //----------------------------------------------------------------------------- // Description: // // preconditions: // p is not on an edge or a vertex. -template +template typename Trapezoidal_decomposition_2::Td_map_item& -Trapezoidal_decomposition_2 -::vertical_ray_shoot(const Point & p,Locate_type & lt, - const bool up_direction /*=true*/) const +Trapezoidal_decomposition_2:: +vertical_ray_shoot(const Point & p,Locate_type & lt, + const bool up_direction /*=true*/) const { #ifdef CGAL_TD_DEBUG CGAL_assertion(traits); @@ -2055,14 +1935,12 @@ Trapezoidal_decomposition_2 Dag_node curr = *m_dag_root; - lt = search_using_dag(curr, traits, p, m_empty_he_handle , - up_direction ? - CGAL::LARGER : CGAL::SMALLER); + lt = search_using_dag(curr, traits, p, m_empty_he_handle, up_direction ? + CGAL::LARGER : CGAL::SMALLER); Td_map_item& item(curr.get_data()); - if (traits->is_td_trapezoid(item)) - { + if (traits->is_td_trapezoid(item)) { CGAL_assertion(traits->is_active(item)); /* using exact traits, it may happen that p is on the right side of the trapezoid directly under its @@ -2076,30 +1954,30 @@ Trapezoidal_decomposition_2 p x------x */ - Td_active_trapezoid& tr (boost::get(item)); + Td_active_trapezoid& tr(boost::get(item)); if ((up_direction && !tr.is_on_right_boundary() && - (traits->compare_curve_end_x_2_object() + (traits->compare_curve_end_x_2_object() (p,traits->vtx_to_ce(tr.right())) == EQUAL) && - (tr.is_on_left_boundary() || + (tr.is_on_left_boundary() || !traits->equal_curve_end_2_object()(traits->vtx_to_ce(tr.left()), traits->vtx_to_ce(tr.right())))) || (!up_direction && !tr.is_on_left_boundary() && - (traits->compare_curve_end_x_2_object() + (traits->compare_curve_end_x_2_object() (p,traits->vtx_to_ce(tr.left())) == EQUAL) && - (tr.is_on_right_boundary() || + (tr.is_on_right_boundary() || !traits->equal_curve_end_2_object()(traits->vtx_to_ce(tr.left()), traits->vtx_to_ce(tr.right()))))) { // recalculate vertical ray shoot using locate on point return up_direction ? - locate(traits->vtx_to_ce(tr.right()),lt) : locate(traits->vtx_to_ce(tr.left()),lt); + locate(traits->vtx_to_ce(tr.right()),lt) : + locate(traits->vtx_to_ce(tr.left()),lt); } if (up_direction ? tr.is_on_top_boundary() : tr.is_on_bottom_boundary()) lt = UNBOUNDED_TRAPEZOID; - else - lt = TRAPEZOID; + else lt = TRAPEZOID; } return item; @@ -2109,7 +1987,7 @@ Trapezoidal_decomposition_2 //----------------------------------------------------------------------------- //// Description: //// -//template +//template //void Trapezoidal_decomposition_2 //::before_split_edge(const X_monotone_curve_2& cv, // const X_monotone_curve_2& cv1, @@ -2281,7 +2159,7 @@ Trapezoidal_decomposition_2 //MICHAL: commented due to inefficient depth update, remove and insert instead -//template +//template //void Trapezoidal_decomposition_2 //::split_edge(const X_monotone_curve_2& cv,Halfedge_const_handle he1, // Halfedge_const_handle he2) @@ -2685,11 +2563,11 @@ Trapezoidal_decomposition_2 //----------------------------------------------------------------------------- // Description: // -template -void Trapezoidal_decomposition_2 -::merge_edge (Halfedge_const_handle he1, - Halfedge_const_handle he2, - const X_monotone_curve_2& cv) +template +void Trapezoidal_decomposition_2:: +merge_edge(Halfedge_const_handle he1, + Halfedge_const_handle he2, + const X_monotone_curve_2& cv) { //make sure the halfedge is valid CGAL_precondition_code(Halfedge_const_handle invalid_he); @@ -2704,25 +2582,20 @@ void Trapezoidal_decomposition_2 write(std::cout,*m_dag_root,*traits) << std::endl; #endif - if (m_with_guarantees) - update(); + if (m_with_guarantees) update(); #ifndef CGAL_NO_TRAPEZOIDAL_DECOMPOSITION_2_OPTIMIZATION - locate_opt_empty(); - #endif const X_monotone_curve_2& cv1 = he1->curve(); const X_monotone_curve_2& cv2 = he2->curve(); - if (!traits) - { + if (!traits) { CGAL_warning(traits != NULL); return; } - if (!traits->are_mergeable_2_object() (cv1, cv2)) - { + if (!traits->are_mergeable_2_object() (cv1, cv2)) { CGAL_warning(traits->are_mergeable_2_object() (cv1, cv2)); return; } @@ -2730,58 +2603,52 @@ void Trapezoidal_decomposition_2 // Calculate the common/merged point (Curve_end) of cv1 and cv2. // There should be one! Curve_end ce = traits->equal_curve_end_2_object() - (Curve_end(cv1,ARR_MAX_END),Curve_end(cv2,ARR_MIN_END)) ? - Curve_end(cv1,ARR_MAX_END) : + (Curve_end(cv1,ARR_MAX_END), Curve_end(cv2, ARR_MIN_END)) ? + Curve_end(cv1, ARR_MAX_END) : // [-- cv1 -->] p [-- cv2 -->] or [<-- cv2 --] p [<-- cv1 --] - traits->equal_curve_end_2_object() - (Curve_end(cv1,ARR_MIN_END),Curve_end(cv2,ARR_MAX_END)) ? + traits->equal_curve_end_2_object() + (Curve_end(cv1, ARR_MIN_END), Curve_end(cv2, ARR_MAX_END)) ? // [<-- cv1 --] p [<-- cv2 --] or [-- cv2 -->] p [-- cv1 -->] - Curve_end(cv1,ARR_MIN_END) : // - traits->equal_curve_end_2_object() - (Curve_end(cv1,ARR_MIN_END),Curve_end(cv2,ARR_MIN_END)) ? + Curve_end(cv1, ARR_MIN_END) : // + traits->equal_curve_end_2_object() + (Curve_end(cv1, ARR_MIN_END), Curve_end(cv2, ARR_MIN_END)) ? // [<-- cv1 --] p [-- cv2 -->] - Curve_end(cv1,ARR_MIN_END) : + Curve_end(cv1, ARR_MIN_END) : // [-- cv1 -->] p [<-- cv2 --] - Curve_end(cv1,ARR_MAX_END); + Curve_end(cv1, ARR_MAX_END); //find the halfedge that will contain the merged curve // [<-- cv1 --] p [<-- cv2 --] or [<-- cv1 --] p [-- cv2 -->]-> he1->twin() // [-- cv1 -->] p [-- cv2 -->] or [-- cv1 -->] p [<-- cv2 --]-> he1 // Notice the curve cv is not yet updated Halfedge_const_handle merged_he = - (traits->equal_curve_end_2_object() - (Curve_end(cv1, ARR_MIN_END), Curve_end(cv2, ARR_MAX_END)) || - traits->equal_curve_end_2_object() - (Curve_end(cv1, ARR_MIN_END), Curve_end(cv2, ARR_MIN_END)) ) - ? he1->twin() : he1; + (traits->equal_curve_end_2_object()(Curve_end(cv1, ARR_MIN_END), + Curve_end(cv2, ARR_MAX_END)) || + traits->equal_curve_end_2_object()(Curve_end(cv1, ARR_MIN_END), + Curve_end(cv2, ARR_MIN_END))) ? + he1->twin() : he1; #ifdef CGAL_TD_DEBUG // ce is interior to the union curve - CGAL_precondition( - is_end_point_left_low (Curve_end(cv, ARR_MIN_END), ce)); - CGAL_precondition( - is_end_point_right_top (Curve_end(cv, ARR_MAX_END), ce)); - + CGAL_precondition(is_end_point_left_low(Curve_end(cv, ARR_MIN_END), ce)); + CGAL_precondition(is_end_point_right_top(Curve_end(cv, ARR_MAX_END), ce)); #endif //get the leftmost & rightmost Curve_end-s - Curve_end leftmost (cv, ARR_MIN_END); - Curve_end rightmost (cv, ARR_MAX_END); + Curve_end leftmost(cv, ARR_MIN_END); + Curve_end rightmost(cv, ARR_MAX_END); //locate the leftmost, rightmost and the merged point in the data structure Locate_type lt1,lt2,lt; - Td_map_item leftp_item = locate (leftmost, lt1); - Td_map_item rightp_item = locate (rightmost, lt2); - Td_map_item mrgp_item = locate (ce, lt); - + Td_map_item leftp_item = locate(leftmost, lt1); + Td_map_item rightp_item = locate(rightmost, lt2); + Td_map_item mrgp_item = locate(ce, lt); //varifying that all trapezoids are not NULL and are of type POINT - CGAL_warning (boost::apply_visitor(dag_node_visitor(),leftp_item) != NULL); - CGAL_warning (boost::apply_visitor(dag_node_visitor(),rightp_item)!= NULL); - CGAL_warning (boost::apply_visitor(dag_node_visitor(),mrgp_item) != NULL); - - + CGAL_warning(boost::apply_visitor(dag_node_visitor(), leftp_item) != NULL); + CGAL_warning(boost::apply_visitor(dag_node_visitor(), rightp_item)!= NULL); + CGAL_warning(boost::apply_visitor(dag_node_visitor(), mrgp_item) != NULL); //define the left curve and the right curve, according // to the common point (that is merged) @@ -2789,8 +2656,7 @@ void Trapezoidal_decomposition_2 const X_monotone_curve_2* p_right_cv = &cv1; Halfedge_const_handle left_he = he2; Halfedge_const_handle right_he = he1; - if (traits->equal_curve_end_2_object() (Curve_end (cv2, ARR_MIN_END), ce)) - { + if (traits->equal_curve_end_2_object()(Curve_end (cv2, ARR_MIN_END), ce)) { p_left_cv = &cv1; p_right_cv = &cv2; left_he = he1; @@ -2804,54 +2670,54 @@ void Trapezoidal_decomposition_2 //CGAL_assertion (traits->equal_curve_end_2_object() // (rightp_item.left(), rightmost)); - CGAL_assertion (is_end_point_left_low(leftmost, ce)); - CGAL_assertion (is_end_point_left_low(ce, rightmost)); + CGAL_assertion(is_end_point_left_low(leftmost, ce)); + CGAL_assertion(is_end_point_left_low(ce, rightmost)); //compare left cv min with leftmost - CGAL_assertion (traits->equal_curve_end_2_object() - (Curve_end(*p_left_cv, ARR_MIN_END), leftmost)); + CGAL_assertion(traits->equal_curve_end_2_object() + (Curve_end(*p_left_cv, ARR_MIN_END), leftmost)); //compare left cv max with ce - CGAL_assertion (traits->equal_curve_end_2_object() - (Curve_end(*p_left_cv, ARR_MAX_END), ce)); + CGAL_assertion(traits->equal_curve_end_2_object() + (Curve_end(*p_left_cv, ARR_MAX_END), ce)); //compare right cv min with ce - CGAL_assertion (traits->equal_curve_end_2_object() - (Curve_end(*p_right_cv, ARR_MIN_END), ce)); + CGAL_assertion(traits->equal_curve_end_2_object() + (Curve_end(*p_right_cv, ARR_MIN_END), ce)); //compare right cv max with rightmost - CGAL_assertion (traits->equal_curve_end_2_object() - (Curve_end(*p_right_cv, ARR_MAX_END), rightmost)); + CGAL_assertion(traits->equal_curve_end_2_object() + (Curve_end(*p_right_cv, ARR_MAX_END), rightmost)); #endif //get the nodes of leftmost point and merge point - Dag_node& leftp_node = *(boost::apply_visitor(dag_node_visitor(),leftp_item)); - Dag_node& mrgp_node = *(boost::apply_visitor(dag_node_visitor(),mrgp_item)); + Dag_node& leftp_node = *(boost::apply_visitor(dag_node_visitor(), leftp_item)); + Dag_node& mrgp_node = *(boost::apply_visitor(dag_node_visitor(), mrgp_item)); //set iterators for below left curve, on left curve & above left curve In_face_iterator - btm_left_it (follow_curve (leftp_node, *p_left_cv, SMALLER)), - mid_left_it (follow_curve (leftp_node, *p_left_cv, EQUAL)), - top_left_it (follow_curve (leftp_node, *p_left_cv, LARGER)); + btm_left_it(follow_curve(leftp_node, *p_left_cv, SMALLER)), + mid_left_it(follow_curve(leftp_node, *p_left_cv, EQUAL)), + top_left_it(follow_curve(leftp_node, *p_left_cv, LARGER)); //set iterators for below right curve, on right curve & above right curve In_face_iterator - btm_right_it (follow_curve (mrgp_node, *p_right_cv, SMALLER)), - mid_right_it (follow_curve (mrgp_node, *p_right_cv, EQUAL)), - top_right_it (follow_curve (mrgp_node, *p_right_cv, LARGER)); + btm_right_it(follow_curve(mrgp_node, *p_right_cv, SMALLER)), + mid_right_it(follow_curve(mrgp_node, *p_right_cv, EQUAL)), + top_right_it(follow_curve(mrgp_node, *p_right_cv, LARGER)); #ifdef CGAL_TD_DEBUG - CGAL_assertion (btm_left_it.operator->()); - CGAL_assertion (mid_left_it.operator->()); - CGAL_assertion (top_left_it.operator->()); - CGAL_assertion (btm_right_it.operator->()); - CGAL_assertion (mid_right_it.operator->()); - CGAL_assertion (top_right_it.operator->()); - CGAL_assertion (traits->is_active(*btm_left_it.operator->())); - CGAL_assertion (traits->is_active(*mid_left_it.operator->())); - CGAL_assertion (traits->is_active(*top_left_it.operator->())); - CGAL_assertion (traits->is_active(*btm_right_it.operator->())); - CGAL_assertion (traits->is_active(*mid_right_it.operator->())); - CGAL_assertion (traits->is_active(*top_right_it.operator->())); + CGAL_assertion(btm_left_it.operator->()); + CGAL_assertion(mid_left_it.operator->()); + CGAL_assertion(top_left_it.operator->()); + CGAL_assertion(btm_right_it.operator->()); + CGAL_assertion(mid_right_it.operator->()); + CGAL_assertion(top_right_it.operator->()); + CGAL_assertion(traits->is_active(*btm_left_it.operator->())); + CGAL_assertion(traits->is_active(*mid_left_it.operator->())); + CGAL_assertion(traits->is_active(*top_left_it.operator->())); + CGAL_assertion(traits->is_active(*btm_right_it.operator->())); + CGAL_assertion(traits->is_active(*mid_right_it.operator->())); + CGAL_assertion(traits->is_active(*top_right_it.operator->())); #endif @@ -2869,76 +2735,81 @@ void Trapezoidal_decomposition_2 Td_map_item dummy2 = Td_map_item(0); Vertex_const_handle leftmost_v = - (left_he->direction() == ARR_LEFT_TO_RIGHT) ? left_he->source() : - left_he->target(); + (left_he->direction() == ARR_LEFT_TO_RIGHT) ? + left_he->source() : left_he->target(); Vertex_const_handle rightmost_v = - (right_he->direction() == ARR_LEFT_TO_RIGHT) ? right_he->target() : - right_he->source(); + (right_he->direction() == ARR_LEFT_TO_RIGHT) ? + right_he->target() : right_he->source(); //replacing the given curve with a new Halfedge_handle along the trapezoids // starting at the iterator, until the end (last parameter) is reached. // updating the last param as the last updated trapzoid - update_map_items_after_merge (mid_left_it, left_he, merged_he, - leftmost_v, rightmost_v, on_cv_left); - update_map_items_after_merge (mid_right_it, right_he, merged_he, - leftmost_v, rightmost_v, right_cv_fraction_item); - update_map_items_after_merge (top_left_it, left_he, merged_he, - leftmost_v, rightmost_v, above_cv_left); - update_map_items_after_merge (top_right_it, right_he, merged_he, - leftmost_v, rightmost_v, dummy1); - update_map_items_after_merge (btm_left_it, left_he, merged_he, - leftmost_v, rightmost_v, below_cv_left); - update_map_items_after_merge (btm_right_it, right_he, merged_he, - leftmost_v, rightmost_v, dummy2); - + update_map_items_after_merge(mid_left_it, left_he, merged_he, + leftmost_v, rightmost_v, on_cv_left); + update_map_items_after_merge(mid_right_it, right_he, merged_he, + leftmost_v, rightmost_v, right_cv_fraction_item); + update_map_items_after_merge(top_left_it, left_he, merged_he, + leftmost_v, rightmost_v, above_cv_left); + update_map_items_after_merge(top_right_it, right_he, merged_he, + leftmost_v, rightmost_v, dummy1); + update_map_items_after_merge(btm_left_it, left_he, merged_he, + leftmost_v, rightmost_v, below_cv_left); + update_map_items_after_merge(btm_right_it, right_he, merged_he, + leftmost_v, rightmost_v, dummy2); // merge trapezoids that were split by the upward and downward // vertical extensions from ce (the merged point) // make sure only active trapezoids are merged - CGAL_assertion( traits->is_active(above_cv_left) && traits->is_active(above_cv_right) ); - CGAL_assertion( traits->is_active(below_cv_left) && traits->is_active(below_cv_right) ); + CGAL_assertion(traits->is_active(above_cv_left) && + traits->is_active(above_cv_right) ); + CGAL_assertion(traits->is_active(below_cv_left) && + traits->is_active(below_cv_right) ); - merge_if_possible (above_cv_left, above_cv_right); - merge_if_possible (below_cv_left, below_cv_right); + merge_if_possible(above_cv_left, above_cv_right); + merge_if_possible(below_cv_left, below_cv_right); // mark older trapezoids as inactive - nodes depth are updated here - Dag_node* above_cv_right_node (boost::apply_visitor(dag_node_visitor(),above_cv_right)); - Dag_node* above_cv_left_node (boost::apply_visitor(dag_node_visitor(),above_cv_left)); - deactivate_trapezoid( *above_cv_right_node, above_cv_left_node); //above_cv_right->remove(above_cv_left->dag_node()); - Dag_node* below_cv_right_node (boost::apply_visitor(dag_node_visitor(),below_cv_right)); - Dag_node* below_cv_left_node (boost::apply_visitor(dag_node_visitor(),below_cv_left)); - deactivate_trapezoid( *below_cv_right_node, below_cv_left_node); //below_cv_right->remove(below_cv_left->dag_node()); + Dag_node* above_cv_right_node(boost::apply_visitor(dag_node_visitor(), + above_cv_right)); + Dag_node* above_cv_left_node(boost::apply_visitor(dag_node_visitor(), + above_cv_left)); + deactivate_trapezoid( *above_cv_right_node, above_cv_left_node); + //above_cv_right->remove(above_cv_left->dag_node()); + Dag_node* below_cv_right_node(boost::apply_visitor(dag_node_visitor(), + below_cv_right)); + Dag_node* below_cv_left_node(boost::apply_visitor(dag_node_visitor(), + below_cv_left)); + deactivate_trapezoid( *below_cv_right_node, below_cv_left_node); + //below_cv_right->remove(below_cv_left->dag_node()); update_largest_leaf_depth((std::max)(above_cv_left_node->depth(), below_cv_left_node->depth())); //no need to update m_number_of_dag_nodes because the number of nodes did not change. #ifdef CGAL_TD_DEBUG - - CGAL_warning (!traits->is_empty_item(on_cv_left)); - CGAL_warning (!traits->is_empty_item(on_cv_right)); - + CGAL_warning(!traits->is_empty_item(on_cv_left)); + CGAL_warning(!traits->is_empty_item(on_cv_right)); #endif // make the merged point's representative inactive deactivate_vertex(mrgp_node); //mrgp_node->remove(); - CGAL_assertion(traits->is_td_edge(on_cv_left) && traits->is_active(on_cv_left)); + CGAL_assertion(traits->is_td_edge(on_cv_left) && + traits->is_active(on_cv_left)); - Td_active_edge& e_left (boost::get(on_cv_left)); + Td_active_edge& e_left(boost::get(on_cv_left)); e_left.set_next(on_cv_right); - CGAL_assertion(traits->is_td_edge(on_cv_right) && traits->is_active(on_cv_right)); + CGAL_assertion(traits->is_td_edge(on_cv_right) && + traits->is_active(on_cv_right)); //replacing the curve in the end points' trapezoids themselves (updating top/ bottom) - update_vtx_cw_he_after_merge (*p_left_cv, merged_he, leftp_item); - update_vtx_cw_he_after_merge (*p_right_cv, merged_he, rightp_item); //MICHAL: maybe I should pass the he1 & he2? + update_vtx_cw_he_after_merge(*p_left_cv, merged_he, leftp_item); + update_vtx_cw_he_after_merge(*p_right_cv, merged_he, rightp_item); //MICHAL: maybe I should pass the he1 & he2? #ifdef CGAL_TD_DEBUG - CGAL_warning(!traits->is_empty_item(left_cv_fraction_item)); CGAL_warning(!traits->is_empty_item(right_cv_fraction_item)); - #endif // reevaluating number of curves @@ -2949,67 +2820,57 @@ void Trapezoidal_decomposition_2 << is_valid(*m_dag_root) << std::endl; write(std::cout,*m_dag_root,*traits) << std::endl; #endif - } - //----------------------------------------------------------------------------- // Description: // -template +template unsigned long -Trapezoidal_decomposition_2 -::longest_query_path_length_rec(bool minus_inf, Dag_node& min_node, - bool plus_inf, Dag_node& max_node, - Dag_node& node) +Trapezoidal_decomposition_2:: +longest_query_path_length_rec(bool minus_inf, Dag_node& min_node, + bool plus_inf, Dag_node& max_node, + Dag_node& node) { //if NULL - if (node.is_null()) - return 0; + if (node.is_null()) return 0; //if not valid range or empty return 0 - if (!minus_inf && !plus_inf) - { + if (!minus_inf && !plus_inf) { Td_map_item min_node_item(min_node.get_data()); - if (traits->is_fictitious_vertex(min_node_item)) - { + if (traits->is_fictitious_vertex(min_node_item)) { const Curve_end min_ce(*(boost::apply_visitor(curve_end_for_fict_vertex_visitor(),min_node_item))); Td_map_item max_node_item(max_node.get_data()); - if (traits->is_fictitious_vertex(max_node_item)) - { + if (traits->is_fictitious_vertex(max_node_item)) { const Curve_end max_ce(*(boost::apply_visitor(curve_end_for_fict_vertex_visitor(),max_node_item))); //min-fict, max-fict - if (!is_end_point_left_low(min_ce, max_ce)) - return 0; + if (!is_end_point_left_low(min_ce, max_ce)) return 0; } - else - { - const Point& max_p(boost::apply_visitor(point_for_vertex_visitor(),max_node_item)); + else { + const Point& max_p(boost::apply_visitor(point_for_vertex_visitor(), + max_node_item)); //min-fict, max-pt //if smaller than the point represented by min_node - if (!is_end_point_left_low(min_ce, max_p)) - return 0; + if (!is_end_point_left_low(min_ce, max_p)) return 0; } } - else - { - const Point& min_p(boost::apply_visitor(point_for_vertex_visitor(),min_node_item)); + else { + const Point& min_p(boost::apply_visitor(point_for_vertex_visitor(), + min_node_item)); Td_map_item max_node_item(max_node.get_data()); - if (traits->is_fictitious_vertex(max_node_item)) - { + if (traits->is_fictitious_vertex(max_node_item)) { const Curve_end max_ce(*(boost::apply_visitor(curve_end_for_fict_vertex_visitor(),max_node_item))); //min-pt, max-fict - if (!is_end_point_left_low(min_p, max_ce)) - return 0; + if (!is_end_point_left_low(min_p, max_ce)) return 0; } - else - { - const Point& max_p(boost::apply_visitor(point_for_vertex_visitor(),max_node_item)); + else { + const Point& max_p(boost::apply_visitor(point_for_vertex_visitor(), + max_node_item)); //min-pt, max-pt //if smaller than the point represented by min_node @@ -3019,20 +2880,18 @@ Trapezoidal_decomposition_2 } } - //if node represents a trapezoid - if (traits->is_td_trapezoid(node.get_data()) ) - return 1; + if (traits->is_td_trapezoid(node.get_data())) return 1; //if node represents a curve - if (!traits->is_td_vertex(node.get_data()) ) + if (!traits->is_td_vertex(node.get_data())) return (1 + (std::max)( - longest_query_path_length_rec(minus_inf, min_node, - plus_inf, max_node, - node.left_child()) , - longest_query_path_length_rec(minus_inf, min_node, - plus_inf, max_node, - node.right_child()) )); + longest_query_path_length_rec(minus_inf, min_node, + plus_inf, max_node, + node.left_child()) , + longest_query_path_length_rec(minus_inf, min_node, + plus_inf, max_node, + node.right_child()))); //if node represents a vertex Td_map_item curr_item(node.get_data()); @@ -3040,28 +2899,23 @@ Trapezoidal_decomposition_2 //if node is smaller than min, use min in the next recursion min bound, otherwise use node Dag_node new_min_node = node; - if (!minus_inf) - { + if (!minus_inf) { Td_map_item min_node_item(min_node.get_data()); - if (traits->is_fictitious_vertex(min_node_item)) - { + if (traits->is_fictitious_vertex(min_node_item)) { const Curve_end min_ce(*(boost::apply_visitor(curve_end_for_fict_vertex_visitor(),min_node_item))); //if smaller than the point represented by min_node //if ((is_fict_vtx && is_end_point_left_low(*(boost::apply_visitor(curve_end_for_fict_vertex_visitor(),curr_item)), min_ce)) || // (!is_fict_vtx && is_end_point_left_low(boost::apply_visitor(point_for_vertex_visitor(), curr_item), min_ce) )) - if (is_end_point_right_top(min_ce, node)) - { + if (is_end_point_right_top(min_ce, node)) { new_min_node = min_node; } } - else - { + else { const Point& min_p(boost::apply_visitor(point_for_vertex_visitor(),min_node_item)); //if smaller than the point represented by min_node //if ((is_fict_vtx && is_end_point_left_low(*(boost::apply_visitor(curve_end_for_fict_vertex_visitor(),curr_item)), min_p)) || // (!is_fict_vtx && is_end_point_left_low(boost::apply_visitor(point_for_vertex_visitor(), curr_item), min_p) )) - if (is_end_point_right_top(min_p, node)) - { + if (is_end_point_right_top(min_p, node)) { new_min_node = min_node; } } @@ -3069,11 +2923,9 @@ Trapezoidal_decomposition_2 //if node is larger than max, use max in the next recursion max bound, otherwise use node Dag_node new_max_node = node; - if (!plus_inf) - { + if (!plus_inf) { Td_map_item max_node_item(max_node.get_data()); - if (traits->is_fictitious_vertex(max_node_item)) - { + if (traits->is_fictitious_vertex(max_node_item)) { const Curve_end max_ce(*(boost::apply_visitor(curve_end_for_fict_vertex_visitor(),max_node_item))); //if larger than the point represented by max_node //if ((is_fict_vtx && is_end_point_right_top(*(boost::apply_visitor(curve_end_for_fict_vertex_visitor(),curr_item)), max_ce)) || @@ -3083,31 +2935,26 @@ Trapezoidal_decomposition_2 new_max_node = max_node; } } - else - { - const Point& max_p(boost::apply_visitor(point_for_vertex_visitor(),max_node_item)); + else { + const Point& max_p(boost::apply_visitor(point_for_vertex_visitor(), + max_node_item)); //if smaller than the point represented by min_node //if ((is_fict_vtx && is_end_point_right_top(*(boost::apply_visitor(curve_end_for_fict_vertex_visitor(),curr_item)), max_p)) || // (!is_fict_vtx && is_end_point_right_top(boost::apply_visitor(point_for_vertex_visitor(), curr_item), max_p) )) - if (is_end_point_left_low(max_p, node)) - { + if (is_end_point_left_low(max_p, node)) { new_max_node = max_node; } } } //o/w continue with updated parameters - return (1 + (std::max)( - longest_query_path_length_rec(minus_inf, min_node, - false, new_max_node, - node.left_child()) , - longest_query_path_length_rec(false, new_min_node, - plus_inf, max_node, - node.right_child()) )); - + return (1 + (std::max)(longest_query_path_length_rec(minus_inf, min_node, + false, new_max_node, + node.left_child()) , + longest_query_path_length_rec(false, new_min_node, + plus_inf, max_node, + node.right_child()))); } - - } //namespace CGAL #endif diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_traits_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_traits_2.h index 34c7931e702..ef0d6e94e4c 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_traits_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_polycurve_traits_2.h @@ -163,6 +163,9 @@ public: /// \name Construction functors(based on the subcurve traits). //@{ +#ifndef DOXYGEN_RUNNING + class Push_back_2; +#endif /*! \class * A functor that divides an arc into x-monotone arcs. That are, arcs that * do not cross the identification arc. diff --git a/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/Curved_kernel_via_analysis_2_functors.h b/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/Curved_kernel_via_analysis_2_functors.h index 97c81889536..9520105d9be 100644 --- a/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/Curved_kernel_via_analysis_2_functors.h +++ b/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/Curved_kernel_via_analysis_2_functors.h @@ -1432,7 +1432,7 @@ public: CGAL_CKvA_2_GRAB_BASE_FUNCTOR_TYPES //! the result type - typedef CGAL::iterator< std::output_iterator_tag, CGAL::Object > + typedef CGAL::cpp98::iterator< std::output_iterator_tag, CGAL::Object > result_type; //! the arity of the functor @@ -1888,7 +1888,7 @@ public: CGAL_CKvA_2_GRAB_BASE_FUNCTOR_TYPES //! the result type - typedef CGAL::iterator< std::output_iterator_tag, CGAL::Object > + typedef CGAL::cpp98::iterator< std::output_iterator_tag, CGAL::Object > result_type; //! the arity of the functor @@ -2511,7 +2511,7 @@ public: typedef typename Curve_analysis_2::Coordinate_2 Coordinate_2; //! the result type - typedef CGAL::iterator< std::output_iterator_tag, Coordinate_2 > + typedef CGAL::cpp98::iterator< std::output_iterator_tag, Coordinate_2 > result_type; //! the arity of the functor @@ -2576,7 +2576,7 @@ public: typedef typename Curve_analysis_2::Coordinate_2 Coordinate_2; //! the result type - typedef CGAL::iterator< std::output_iterator_tag, Coordinate_2 > + typedef CGAL::cpp98::iterator< std::output_iterator_tag, Coordinate_2 > result_type; //! the arity of the functor diff --git a/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/Make_x_monotone_2.h b/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/Make_x_monotone_2.h index e9f9fd3e5ee..1e2b630628d 100644 --- a/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/Make_x_monotone_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/Make_x_monotone_2.h @@ -57,9 +57,9 @@ template < class CurvedKernelViaAnalysis_2, class ConstructArc_2 = typename CurvedKernelViaAnalysis_2::Construct_arc_2 > struct Make_x_monotone_2 : - public CGAL::binary_function< typename CurvedKernelViaAnalysis_2::Curve_2, - CGAL::iterator, - CGAL::iterator > { + public CGAL::cpp98::binary_function< typename CurvedKernelViaAnalysis_2::Curve_2, + CGAL::cpp98::iterator, + CGAL::cpp98::iterator > { //!\name Public types //!@{ diff --git a/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/Sweep_curves_adapter_2.h b/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/Sweep_curves_adapter_2.h index d998a3e5600..57cc08578ce 100644 --- a/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/Sweep_curves_adapter_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/Sweep_curves_adapter_2.h @@ -693,7 +693,7 @@ class Make_x_monotone_2 typedef typename SweepCurvesAdapter_2::Generic_arc_2 Generic_arc_2; public: - typedef CGAL::iterator + typedef CGAL::cpp98::iterator result_type; //! standard constructor diff --git a/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/test/simple_models.h b/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/test/simple_models.h index 18be69ec131..fd8b7384c34 100644 --- a/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/test/simple_models.h +++ b/Arrangement_on_surface_2/include/CGAL/Curved_kernel_via_analysis_2/test/simple_models.h @@ -1041,7 +1041,7 @@ public: //! \brief constructs \c Curve_analysis_2 object, uses caching if appropriate struct Construct_curve_2 : - public CGAL::unary_function< Polynomial_2, Curve_analysis_2 > + public CGAL::cpp98::unary_function< Polynomial_2, Curve_analysis_2 > { //! \brief constructs an object from \c Algebraic_curve_kernel_2 type //! no default constructor provided @@ -1060,7 +1060,7 @@ public: * caching is used when appropriate */ struct Construct_curve_pair_2 : - public CGAL::binary_function { Curve_pair_analysis_2 operator() @@ -1078,7 +1078,7 @@ public: //! returns the first coordinate of \c Xy_coordinate_2 struct Get_x_2 : - public CGAL::unary_function { + public CGAL::cpp98::unary_function { Algebraic_real_1 operator()(const Xy_coordinate_2& xy) const { return xy.x(); @@ -1088,7 +1088,7 @@ public: //! returns the second coordinate of \c Xy_coordinate_2 struct Get_y_2 : - public CGAL::unary_function { + public CGAL::cpp98::unary_function { Algebraic_real_1 operator()(const Xy_coordinate_2& xy) const { return xy.y(); @@ -1097,7 +1097,7 @@ public: CGAL_Algebraic_Kernel_cons(Get_y_2, Get_y_2_object); struct Refine_x_2 : - public CGAL::unary_function { + public CGAL::cpp98::unary_function { void operator()(const Xy_coordinate_2& r) const { } @@ -1106,7 +1106,7 @@ public: CGAL_Algebraic_Kernel_pred(Refine_x_2, refine_x_2_object); struct Refine_y_2 : - public CGAL::unary_function { + public CGAL::cpp98::unary_function { void operator()(const Xy_coordinate_2& r) const { } @@ -1196,7 +1196,7 @@ public: //! \brief comparison of x-coordinates struct Compare_x_2 : - public CGAL::binary_function { Comparison_result operator()(const Algebraic_real_1& x1, @@ -1212,7 +1212,7 @@ public: //! \brief comparison of y-coordinates of two points struct Compare_y_2 : - public CGAL::binary_function< Xy_coordinate_2, Xy_coordinate_2, + public CGAL::cpp98::binary_function< Xy_coordinate_2, Xy_coordinate_2, Comparison_result > { Comparison_result operator()(const Xy_coordinate_2& xy1, @@ -1226,7 +1226,7 @@ public: //! //! \c equal_x specifies that only y-coordinates need to be compared struct Compare_xy_2 : - public CGAL::binary_function { Comparison_result operator()(const Xy_coordinate_2& xy1, @@ -1243,7 +1243,7 @@ public: //! for algerbaic curves this means that supporting polynomial is //! square-free struct Has_finite_number_of_self_intersections_2 : - public CGAL::unary_function< Polynomial_2, bool > { + public CGAL::cpp98::unary_function< Polynomial_2, bool > { bool operator()(const Polynomial_2& p) const { return true; //is_square_free(p); @@ -1258,7 +1258,7 @@ public: //! in case of algerbaic curves: checks whether supporting polynomials are //! coprime struct Has_finite_number_of_intersections_2 : - public CGAL::binary_function< Curve_analysis_2, Curve_analysis_2, bool > { + public CGAL::cpp98::binary_function< Curve_analysis_2, Curve_analysis_2, bool > { bool operator()(const Curve_analysis_2& c1, const Curve_analysis_2& c2) const { @@ -1315,7 +1315,7 @@ public: //! \brief computes the derivative w.r.t. the first (innermost) variable struct Derivative_x_2 : - public CGAL::unary_function< Polynomial_2, Polynomial_2 > { + public CGAL::cpp98::unary_function< Polynomial_2, Polynomial_2 > { Polynomial_2 operator()(const Polynomial_2& p) const { return p; @@ -1325,7 +1325,7 @@ public: //! \brief computes the derivative w.r.t. the first (outermost) variable struct Derivative_y_2 : - public CGAL::unary_function< Polynomial_2, Polynomial_2 > { + public CGAL::cpp98::unary_function< Polynomial_2, Polynomial_2 > { Polynomial_2 operator()(const Polynomial_2& p) const { return p; @@ -1374,7 +1374,7 @@ public: * returns a value convertible to \c CGAL::Sign */ struct Sign_at_2 : - public CGAL::binary_function< Polynomial_2, Xy_coordinate_2, Sign > { + public CGAL::cpp98::binary_function< Polynomial_2, Xy_coordinate_2, Sign > { Sign operator()(const Polynomial_2& p, const Xy_coordinate_2& r) const { diff --git a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_traits_2.h b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_traits_2.h index 1ef10dcf3c9..6df312301ba 100644 --- a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_traits_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_traits_2.h @@ -347,6 +347,9 @@ public: return os; } + class Parameter_space_in_x_2; + class Parameter_space_in_y_2; + /*! A functor that computes intersections between x-monotone curves. */ class Intersect_2 { protected: diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/CMakeLists.txt b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/CMakeLists.txt index 14fc5649284..1e9b152f714 100644 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/CMakeLists.txt +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/CMakeLists.txt @@ -6,7 +6,7 @@ project( Arrangement_on_surface_2_Tests ) enable_testing() -cmake_minimum_required(VERSION 2.8.10) +cmake_minimum_required(VERSION 3.1) find_package(CGAL QUIET COMPONENTS Core) @@ -33,8 +33,7 @@ if ( CGAL_FOUND ) endif() else() - - message(STATUS "This program requires the CGAL library, and will not be compiled.") - -endif() + message(STATUS "This program requires the CGAL library, and will not be compiled.") + +endif() diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/Point_location_dynamic_test.h b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/Point_location_dynamic_test.h index 5735c5884b5..4c851cb0e72 100644 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/Point_location_dynamic_test.h +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/Point_location_dynamic_test.h @@ -132,7 +132,7 @@ read_perform_opts(std::istream& is) rc = false; continue; } - if (cmd == 'i') insert(*(this->m_arr), this->m_xcurves[id]); + if (cmd == 'i') CGAL::insert(*(this->m_arr), this->m_xcurves[id]); if (cmd == 'd') { if (!remove(this->m_xcurves[id])) rc = false; diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/Point_location_test.h b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/Point_location_test.h index 23926c2926d..3224dfe54eb 100644 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/Point_location_test.h +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/Point_location_test.h @@ -1,6 +1,21 @@ #ifndef CGAL_POINT_LOCATION_TEST_H #define CGAL_POINT_LOCATION_TEST_H +#define NAIVE_PL_ENABLED 1 +#define SIMPLE_PL_ENABLED 1 +#define WALK_PL_ENABLED 1 +#define LM_PL_ENABLED 1 +#define LM_RANDOM_PL_ENABLED 1 +#define LM_GRID_PL_ENABLED 1 +#define LM_HALTON_PL_ENABLED 1 +#define LM_MIDDLE_EDGES_PL_ENABLED 1 +#define LM_SPECIFIED_POINTS_PL_ENABLED 1 +#define TRIANGULATION_PL_ENABLED 1 +#define TRAPEZOID_RIC_PL_ENABLED 1 +#define TRAPEZOID_RIC_NO_GUARANTEE_PL_ENABLED 1 + +#include + #include #include #include @@ -22,11 +37,11 @@ #include "IO_test.h" /*! Point location test */ -template -class Point_location_test : public IO_test { +template +class Point_location_test : public IO_test { public: - typedef Geom_traits_T Geom_traits; - typedef Topol_traits_T Topol_traits; + typedef GeomTraits Geom_traits; + typedef TopolTraits Topol_traits; typedef IO_test Base; typedef typename Base::Point_2 Point_2; @@ -64,43 +79,44 @@ public: protected: typedef typename CGAL::Arr_naive_point_location - Naive_point_location; + Naive_pl; typedef typename CGAL::Arr_simple_point_location - Simple_point_location; + Simple_pl; typedef typename CGAL::Arr_walk_along_line_point_location - Walk_point_location; + Walk_pl; typedef typename CGAL::Arr_landmarks_point_location - Lm_point_location; + Lm_pl; typedef typename CGAL::Arr_random_landmarks_generator Random_lm_generator; typedef typename CGAL::Arr_landmarks_point_location - Lm_random_point_location; + Lm_random_pl; typedef typename CGAL::Arr_grid_landmarks_generator Grid_lm_generator; typedef typename CGAL::Arr_landmarks_point_location - Lm_grid_point_location; + Lm_grid_pl; typedef typename CGAL::Arr_halton_landmarks_generator Halton_lm_generator; typedef typename CGAL::Arr_landmarks_point_location - Lm_halton_point_location; + Lm_halton_pl; typedef typename CGAL::Arr_middle_edges_landmarks_generator Middle_edges_generator; typedef typename CGAL::Arr_landmarks_point_location - Lm_middle_edges_point_location; + Lm_middle_edges_pl; typedef typename CGAL::Arr_landmarks_specified_points_generator Specified_points_generator; typedef typename CGAL::Arr_landmarks_point_location - Lm_specified_points_point_location; - typedef typename CGAL::Arr_trapezoid_ric_point_location - Trapezoid_ric_point_location; + Lm_specified_points_pl; typedef CGAL::Arr_triangulation_point_location - Triangulation_point_location; + Triangulation_pl; + + typedef typename CGAL::Arr_trapezoid_ric_point_location + Trapezoid_ric_pl; // ===> Add new point location type here <=== @@ -117,33 +133,65 @@ protected: /*! The query points */ Points_vector m_query_points; - Naive_point_location* m_naive_pl; // 0 - Simple_point_location* m_simple_pl; // 1 - Walk_point_location* m_walk_pl; // 2 - Lm_point_location* m_lm_pl; // 3 - Lm_random_point_location* m_random_lm_pl; // 4 - Lm_grid_point_location* m_grid_lm_pl; // 5 - Lm_halton_point_location* m_halton_lm_pl; // 6 - Lm_middle_edges_point_location* m_middle_edges_lm_pl; // 7 - Lm_specified_points_point_location* m_specified_points_lm_pl; // 8 - Triangulation_point_location* m_triangulation_pl; // 9 - Trapezoid_ric_point_location* m_trapezoid_ric_pl; // 10 - Trapezoid_ric_point_location* m_trapezoid_ric_no_grnt_pl; // 11 + enum Pl_strategy { + NAIVE_PL = 0, + SIMPLE_PL, + WALK_PL, + LM_PL, + LM_RANDOM_PL, + LM_GRID_PL, + LM_HALTON_PL, + LM_MIDDLE_EDGES_PL, + LM_SPECIFIED_POINTS_PL, + TRIANGULATION_PL, + TRAPEZOID_RIC_PL, + TRAPEZOID_RIC_NO_GUARANTEE_PL, + NUM_PL_STRATEGIES + }; + typedef boost::variant Pl_variant; + + struct Locator { + Pl_variant m_variant; + + //! The name of the locator. + std::string m_name; + + bool m_active; + }; + + std::vector m_locators; + + // Landmark point-location generators Random_lm_generator* m_random_g; Grid_lm_generator* m_grid_g; Halton_lm_generator* m_halton_g; Middle_edges_generator* m_middle_edges_g; Specified_points_generator* m_specified_points_g; - // // ===> Change the number of point-location startegies - // // when a new point location is added. <=== - #define MAX_NUM_POINT_LOCATION_STRATEGIES 12 - - int verify(Objects_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES], + /*! Verify the results (old version). + */ + int verify(Objects_vector objs[NUM_PL_STRATEGIES], size_t size, size_t pls_num); - int verify(Variants_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES], + /*! Verify the results (new version). + */ + int verify(Variants_vector objs[NUM_PL_STRATEGIES], size_t size, size_t pls_num); public: @@ -161,13 +209,13 @@ public: void set_filenames(const char* points_filename, const char* xcurves_filename, const char* curves_filename, const char* queries_filename); - /*! Initialize the data structures */ + //! Initialize the data structures. virtual bool init(); - /*! Perform the test */ + //! Perform the test. virtual bool perform(); - /*! Clear the data structures */ + //! Clear the data structures. virtual void clear(); bool allocate_arrangement(); @@ -191,63 +239,496 @@ public: void query(Point_location& pl, const char* type, InputIterator begin, InputIterator end, OutputIterator oi) { - typedef InputIterator Input_iterator; - + typedef InputIterator Input_iterator; CGAL::Timer timer; timer.reset(); timer.start(); - Input_iterator piter; - for (piter = begin; piter != end; ++piter) { - Point_2 q = (*piter); - *oi++ = pl.locate(q); - } + for (Input_iterator piter = begin; piter != end; ++piter) + *oi++ = pl.locate(*piter); timer.stop(); std::cout << type << " location took " << timer.time() << std::endl; } + +private: + //! Initialize point location. + template + void init_pl(const std::string& name) + { + m_locators[id].m_variant = static_cast(NULL); + m_locators[id].m_name = name; + m_locators[id].m_active = true; + } + + //! Allocate point location. + template + void allocate_pl() + { + Strategy* locator = new Strategy(); + CGAL_assertion(locator); + m_locators[id].m_variant = locator; + } + + //! Construct point location. + template + bool construct_pl() + { + Strategy* locator = new Strategy(*m_arr); + if (! locator) return false; + m_locators[id].m_variant = locator; + return true; + } + + //! Construct landmark point-location with a generator. + template + bool construct_pl(Generator* generator) + { + Strategy* locator = new Strategy(*m_arr, generator); + if (! locator) return false; + m_locators[id].m_variant = locator; + return true; + } + + //! Delete point location. + template + void deallocate_pl() + { + Strategy* strategy = boost::get(m_locators[id].m_variant); + if (strategy) { + delete strategy; + m_locators[id].m_variant = static_cast(NULL); + } + } + + //! Attach point location. + template + void attach_pl() + { + if (! m_locators[id].m_active) return; + Strategy* strategy = boost::get(m_locators[id].m_variant); + strategy->attach(*m_arr); + } + + //! Attach landmark point location with a generator. + template + void attach_pl(Generator* generator) + { + if (! m_locators[id].m_active) return; + Strategy* strategy = boost::get(m_locators[id].m_variant); + strategy->attach(*m_arr, generator); + } + + //! Query using point location. + template + void query_pl(T& objs) + { + if (! m_locators[id].m_active) return; + const std::string& name = m_locators[id].m_name; + Strategy* strategy = boost::get(m_locators[id].m_variant); + query(*strategy, name.c_str(), m_query_points.begin(), m_query_points.end(), + std::back_inserter(objs)); + } + + //! Measure the time consumption of an operation + template + void measure(Timer& timer, UnaryOperation op) + { + if (! m_locators[id].m_active) return; + const std::string& name = m_locators[id].m_name; + timer.reset(); + timer.start(); + op(); + timer.stop(); + std::cout << name.c_str() << " took " << timer.time() << std::endl; + } }; -/*! - * Constructor. - */ -template -Point_location_test:: +// Naive +#if (NAIVE_PL_ENABLED) +#define INIT_PL_NATIVE() init_pl("Naive") +#define ALLOCATE_PL_NATIVE() allocate_pl() +#define CONSTRUCT_PL_NATIVE() construct_pl() +#define DEALLOCATE_PL_NATIVE() deallocate_pl() +#define ATTACH_PL_NATIVE() attach_pl() +#define QUERY_PL_NATIVE(obj) query_pl(obj) +#else +#define INIT_PL_NATIVE() +#define ALLOCATE_PL_NATIVE() +#define CONSTRUCT_PL_NATIVE() +#define DEALLOCATE_PL_NATIVE() +#define ATTACH_PL_NATIVE() +#define QUERY_PL_NATIVE(obj) +#endif + +// Simple +#if (SIMPLE_PL_ENABLED) +#define INIT_PL_SIMPLE() init_pl("Simple") +#define ALLOCATE_PL_SIMPLE() allocate_pl() +#define CONSTRUCT_PL_SIMPLE() construct_pl() +#define DEALLOCATE_PL_SIMPLE() deallocate_pl() +#define ATTACH_PL_SIMPLE() attach_pl() +#define QUERY_PL_SIMPLE(obj) query_pl(obj) +#else +#define INIT_PL_SIMPLE() +#define ALLOCATE_PL_SIMPLE() +#define CONSTRUCT_PL_SIMPLE() +#define DEALLOCATE_PL_SIMPLE() +#define ATTACH_PL_SIMPLE() +#define QUERY_PL_SIMPLE(obj) +#endif + +// Walk +#if (WALK_PL_ENABLED) +#define INIT_PL_WALK() init_pl("Walk") +#define ALLOCATE_PL_WALK() allocate_pl() +#define CONSTRUCT_PL_WALK() construct_pl() +#define DEALLOCATE_PL_WALK() deallocate_pl() +#define ATTACH_PL_WALK() attach_pl() +#define QUERY_PL_WALK(obj) query_pl(obj) +#else +#define INIT_PL_WALK() +#define ALLOCATE_PL_WALK() +#define CONSTRUCT_PL_WALK() +#define DEALLOCATE_PL_WALK() +#define ATTACH_PL_WALK() +#define QUERY_PL_WALK(obj) +#endif + +// Landmarks (vertices) +#if (LM_PL_ENABLED) +#define INIT_PL_LM() init_pl("Landmarks (vertices)"); +#define ALLOCATE_PL_LM() allocate_pl() +#define CONSTRUCT_PL_LM() construct_pl() +#define DEALLOCATE_PL_LM() deallocate_pl() +#define ATTACH_PL_LM() attach_pl() +#define QUERY_PL_LM(obj) query_pl(obj) +#else +#define INIT_PL_LM() +#define ALLOCATE_PL_LM() +#define CONSTRUCT_PL_LM() +#define DEALLOCATE_PL_LM() +#define ATTACH_PL_LM() +#define QUERY_PL_LM(obj) +#endif + +// Landmarks random +#if (LM_RANDOM_PL_ENABLED) +#define INIT_PL_LM_RANDOM() \ + init_pl("Landmarks random"); +#define ALLOCATE_PL_LM_RANDOM() \ + allocate_pl() + +#define CONSTRUCT_PL_LM_RANDOM() \ + m_random_g = new Random_lm_generator(*m_arr); \ + construct_pl(m_random_g) + +#define DEALLOCATE_PL_LM_RANDOM() \ + if (m_random_g) { \ + delete m_random_g; \ + m_random_g = NULL; \ + } \ + deallocate_pl() + +#define ATTACH_PL_LM_RANDOM() \ + m_random_g = new Random_lm_generator(*m_arr); \ + attach_pl(m_random_g) + +#define QUERY_PL_LM_RANDOM(obj) query_pl(obj) +#else +#define INIT_PL_LM_RANDOM() +#define ALLOCATE_PL_LM_RANDOM() +#define CONSTRUCT_PL_LM_RANDOM() +#define DEALLOCATE_PL_LM_RANDOM() +#define ATTACH_PL_LM_RANDOM() +#define QUERY_PL_LM_RANDOM(obj) +#endif + +// Landmarks grid +#if (LM_GRID_PL_ENABLED) +#define INIT_PL_LM_GRID() init_pl("Landmarks grid") +#define ALLOCATE_PL_LM_GRID() allocate_pl() + +#define CONSTRUCT_PL_LM_GRID() \ + m_grid_g = new Grid_lm_generator(*m_arr); \ + construct_pl(m_grid_g) + +#define DEALLOCATE_PL_LM_GRID() \ + if (m_grid_g) { \ + delete m_grid_g; \ + m_grid_g = NULL; \ + } \ + deallocate_pl() + +#define ATTACH_PL_LM_GRID() \ + m_grid_g = new Grid_lm_generator(*m_arr); \ + attach_pl(m_grid_g) + +#define QUERY_PL_LM_GRID(obj) query_pl(obj) +#else +#define INIT_PL_LM_GRID() +#define ALLOCATE_PL_LM_GRID() +#define CONSTRUCT_PL_LM_GRID() +#define DEALLOCATE_PL_LM_GRID() +#define ATTACH_PL_LM_GRID() +#define QUERY_PL_LM_GRID(obj) +#endif + +// Landmarks Halton +#if (LM_HALTON_PL_ENABLED) +#define INIT_PL_LM_HALTON() \ + init_pl("Landmarks Halton") +#define ALLOCATE_PL_LM_HALTON() allocate_pl() + +#define CONSTRUCT_PL_LM_HALTON() \ + m_halton_g = new Halton_lm_generator(*m_arr); \ + construct_pl(m_halton_g) + +#define DEALLOCATE_PL_LM_HALTON() \ + if (m_halton_g) { \ + delete m_halton_g; \ + m_halton_g = NULL; \ + } \ + deallocate_pl() + +#define ATTACH_PL_LM_HALTON() \ + m_halton_g = new Halton_lm_generator(*m_arr); \ + attach_pl(m_halton_g) + +#define QUERY_PL_LM_HALTON(obj) query_pl(obj) +#else +#define INIT_PL_LM_HALTON() +#define ALLOCATE_PL_LM_HALTON() +#define CONSTRUCT_PL_LM_HALTON() +#define DEALLOCATE_PL_LM_HALTON() +#define ATTACH_PL_LM_HALTON() +#define QUERY_PL_LM_HALTON(obj) +#endif + +// Landmarks middle edges +#if (LM_MIDDLE_EDGES_PL_ENABLED) +#define INIT_PL_LM_MIDDLE_EDGES() \ + init_pl("Landmarks middle edges") +#define ALLOCATE_PL_LM_MIDDLE_EDGES() \ + allocate_pl() + +#define CONSTRUCT_PL_LM_MIDDLE_EDGES() \ + m_middle_edges_g = new Middle_edges_generator(*m_arr); \ + construct_pl(m_middle_edges_g) + +#define DEALLOCATE_PL_LM_MIDDLE_EDGES() \ + if (m_middle_edges_g) { \ + delete m_middle_edges_g; \ + m_middle_edges_g = NULL; \ + } \ + deallocate_pl() + +#define ATTACH_PL_LM_MIDDLE_EDGES() \ + m_middle_edges_g = new Middle_edges_generator(*m_arr); \ + attach_pl(m_middle_edges_g) + +#define QUERY_PL_LM_MIDDLE_EDGES(obj) \ + query_pl(obj) +#else +#define INIT_PL_LM_MIDDLE_EDGES() +#define ALLOCATE_PL_LM_MIDDLE_EDGES() +#define CONSTRUCT_PL_LM_MIDDLE_EDGES() +#define DEALLOCATE_PL_LM_MIDDLE_EDGES() +#define ATTACH_PL_LM_MIDDLE_EDGES() +#define QUERY_PL_LM_MIDDLE_EDGES(obj) +#endif + +// Landmarks specified points +#if (LM_SPECIFIED_POINTS_PL_ENABLED) +#define INIT_PL_LM_SPECIFIED_POINTS() \ + init_pl("Landmarks specified points"); +#define ALLOCATE_PL_LM_SPECIFIED_POINTS() \ + allocate_pl() + +#define CONSTRUCT_PL_LM_SPECIFIED_POINTS() \ + m_specified_points_g = new Specified_points_generator(*m_arr); \ + construct_pl(m_specified_points_g) + +#define DEALLOCATE_PL_LM_SPECIFIED_POINTS() \ + if (m_specified_points_g) { \ + delete m_specified_points_g; \ + m_specified_points_g = NULL; \ + } \ + deallocate_pl() + +#define ATTACH_PL_LM_SPECIFIED_POINTS() \ + m_specified_points_g = new Specified_points_generator(*m_arr); \ + attach_pl(m_specified_points_g) + +#define QUERY_PL_LM_SPECIFIED_POINTS(obj) \ + query_pl(obj) +#else +#define INIT_PL_LM_SPECIFIED_POINTS() +#define ALLOCATE_PL_LM_SPECIFIED_POINTS() +#define CONSTRUCT_PL_LM_SPECIFIED_POINTS() +#define DEALLOCATE_PL_LM_SPECIFIED_POINTS() +#define ATTACH_PL_LM_SPECIFIED_POINTS() +#define QUERY_PL_LM_SPECIFIED_POINTS(obj) +#endif + +// Triangulation_pl +#if (TRIANGULATION_PL_ENABLED) +#define INIT_PL_TRIANGULATION_PL() \ + init_pl("Triangulation") +#define ALLOCATE_PL_TRIANGULATION_PL() \ + allocate_pl() +#define CONSTRUCT_PL_TRIANGULATION_PL() \ + construct_pl() +#define DEALLOCATE_PL_TRIANGULATION_PL() \ + deallocate_pl() +#define ATTACH_PL_TRIANGULATION_PL() \ + attach_pl() +#define QUERY_PL_TRIANGULATION_PL(obj) \ + query_pl(obj); +#else +#define INIT_PL_TRIANGULATION_PL() +#define ALLOCATE_PL_TRIANGULATION_PL() +#define CONSTRUCT_PL_TRIANGULATION_PL() +#define DEALLOCATE_PL_TRIANGULATION_PL() +#define ATTACH_PL_TRIANGULATION_PL() +#define QUERY_PL_TRIANGULATION_PL(obj) +#endif + +// Trapezoidal RIC +#if (TRAPEZOID_RIC_PL_ENABLED) +#define INIT_PL_TRAPEZOID_RIC_PL() \ + init_pl("Trapezoidal RIC") +#define ALLOCATE_PL_TRAPEZOID_RIC_PL() \ + allocate_pl() +#define CONSTRUCT_PL_TRAPEZOID_RIC_PL() \ + construct_pl() +#define DEALLOCATE_PL_TRAPEZOID_RIC_PL() \ + deallocate_pl() +#define ATTACH_PL_TRAPEZOID_RIC_PL() \ + attach_pl() +#define QUERY_PL_TRAPEZOID_RIC_PL(obj) \ + query_pl(obj) +#else +#define INIT_PL_TRAPEZOID_RIC_PL() +#define ALLOCATE_PL_TRAPEZOID_RIC_PL() +#define CONSTRUCT_PL_TRAPEZOID_RIC_PL() +#define DEALLOCATE_PL_TRAPEZOID_RIC_PL() +#define ATTACH_PL_TRAPEZOID_RIC_PL() +#define QUERY_PL_TRAPEZOID_RIC_PL(obj) +#endif + +#if (TRAPEZOID_RIC_NO_GUARANTEE_PL_ENABLED) +#define INIT_PL_TRAPEZOID_RIC_NO_GUARANTEE() \ + init_pl("Trapezoidal RIC without guarantees") +#define ALLOCATE_PL_TRAPEZOID_RIC_NO_GUARANTEE() \ + allocate_pl() +#define CONSTRUCT_PL_TRAPEZOID_RIC_NO_GUARANTEE() \ + construct_pl() +#define DEALLOCATE_PL_TRAPEZOID_RIC_NO_GUARANTEE() \ + deallocate_pl() + +#define ATTACH_PL_TRAPEZOID_RIC_NO_GUARANTEE() \ + Pl_variant& var = m_locators[TRAPEZOID_RIC_NO_GUARANTEE_PL].m_variant; \ + Trapezoid_ric_pl* strategy = boost::get(var); \ + strategy->with_guarantees(false); \ + attach_pl() + +#define QUERY_PL_TRAPEZOID_RIC_NO_GUARANTEE(obj) \ + query_pl(obj) +#else +#define INIT_PL_TRAPEZOID_RIC_NO_GUARANTEE() +#define ALLOCATE_PL_TRAPEZOID_RIC_NO_GUARANTEE() +#define CONSTRUCT_PL_TRAPEZOID_RIC_NO_GUARANTEE() +#define DEALLOCATE_PL_TRAPEZOID_RIC_NO_GUARANTEE() +#define ATTACH_PL_TRAPEZOID_RIC_NO_GUARANTEE() +#define QUERY_PL_TRAPEZOID_RIC_NO_GUARANTEE(obj) +#endif + +#if defined(CGAL_CFG_NO_CPP0X_LAMBDAS) +#define MEASURE_NAIVE_PL(timer, op) op +#define MEASURE_SIMPLE_PL(timer, op) op +#define MEASURE_WALK_PL(timer, op) op +#define MEASURE_LM_PL(timer, op) op +#define MEASURE_LM_RANDOM_PL(timer, op) op +#define MEASURE_LM_GRID_PL(timer, op) op +#define MEASURE_LM_HALTON_PL(timer, op) op +#define MEASURE_LM_MIDDLE_EDGES_PL(timer, op) op +#define MEASURE_LM_SPECIFIED_POINTS_PL(timer, op) op +#define MEASURE_TRIANGULATION_PL(timer, op) op +#define MEASURE_TRAPEZOID_RIC_PL(timer, op) op +#define MEASURE_TRAPEZOID_RIC_NO_GUARANTEE_PL(timer, op) op +#else +#define MEASURE_NAIVE_PL(timer, op) measure(timer, [&](){ op; }); +#define MEASURE_SIMPLE_PL(timer, op) measure(timer, [&](){ op; }); +#define MEASURE_WALK_PL(timer, op) measure(timer, [&](){ op; }); +#define MEASURE_LM_PL(timer, op) measure(timer, [&](){ op; }); +#define MEASURE_LM_RANDOM_PL(timer, op) \ + measure(timer, [&](){ op; }); +#define MEASURE_LM_GRID_PL(timer, op) \ + measure(timer, [&](){ op; }); +#define MEASURE_LM_HALTON_PL(timer, op) \ + measure(timer, [&](){ op; }); +#define MEASURE_LM_MIDDLE_EDGES_PL(timer, op) \ + measure(timer, [&](){ op; }); +#define MEASURE_LM_SPECIFIED_POINTS_PL(timer, op) \ + measure(timer, [&](){ op; }); +#define MEASURE_TRIANGULATION_PL(timer, op) \ + measure(timer, [&](){ op; }); +#define MEASURE_TRAPEZOID_RIC_PL(timer, op) \ + measure(timer, [&](){ op; }); +#define MEASURE_TRAPEZOID_RIC_NO_GUARANTEE_PL(timer, op) \ + measure(timer, [&](){ op; }); +#endif + +//! Constructor. +template +Point_location_test:: Point_location_test(const Geom_traits& geom_traits) : Base(geom_traits), m_geom_traits(geom_traits), m_arr(NULL), - m_naive_pl(NULL), - m_simple_pl(NULL), - m_walk_pl(NULL), - m_lm_pl(NULL), - m_random_lm_pl(NULL), - m_grid_lm_pl(NULL), - m_halton_lm_pl(NULL), - m_middle_edges_lm_pl(NULL), - m_specified_points_lm_pl(NULL), - m_triangulation_pl(NULL), - m_trapezoid_ric_pl(NULL), - m_trapezoid_ric_no_grnt_pl(NULL), m_random_g(NULL), m_grid_g(NULL), m_halton_g(NULL), m_middle_edges_g(NULL), m_specified_points_g(NULL) -{} +{ + m_locators.resize(NUM_PL_STRATEGIES); -/*! Set the file names */ -template -void Point_location_test:: -set_filenames(const char* points_filename, - const char* xcurves_filename, - const char* curves_filename, - const char* queries_filename) + INIT_PL_NATIVE(); + INIT_PL_SIMPLE(); + INIT_PL_WALK(); + +#if (TEST_GEOM_TRAITS == SEGMENT_GEOM_TRAITS) || \ + (TEST_GEOM_TRAITS == LINEAR_GEOM_TRAITS) + + INIT_PL_LM(); + INIT_PL_LM_RANDOM(); + INIT_PL_LM_GRID(); + INIT_PL_LM_HALTON(); + INIT_PL_LM_MIDDLE_EDGES(); + INIT_PL_LM_SPECIFIED_POINTS(); + +#endif + +#if (TEST_GEOM_TRAITS == SEGMENT_GEOM_TRAITS) + INIT_PL_TRIANGULATION_PL(); +#endif + + INIT_PL_TRAPEZOID_RIC_PL(); + INIT_PL_TRAPEZOID_RIC_NO_GUARANTEE(); +} + +//! Set the file names. +template +void Point_location_test:: +set_filenames(const char* points_filename, const char* xcurves_filename, + const char* curves_filename, const char* queries_filename) { Base::set_filenames(points_filename, xcurves_filename, curves_filename); m_filename_queries.assign(queries_filename); } -/*! Initialize the data structures */ -template -bool Point_location_test::init() +//! Initialize the data structures. +template +bool Point_location_test::init() { if (!Base::init()) return false; @@ -258,109 +739,52 @@ bool Point_location_test::init() return true; } -/*! Clear the data structures */ -template -void Point_location_test::clear() +//! Clear the data structures. +template +void Point_location_test::clear() { Base::clear(); m_query_points.clear(); m_filename_queries.clear(); } -/*! Clear the data structures */ -template -void Point_location_test:: -deallocate_pl_strategies() +//! Clear the data structures. +template +void Point_location_test::deallocate_pl_strategies() { - if (m_naive_pl) { - delete m_naive_pl; - m_naive_pl = NULL; - } - if (m_simple_pl) { - delete m_simple_pl; - m_simple_pl = NULL; - } - if (m_walk_pl) { - delete m_walk_pl; - m_walk_pl = NULL; - } + DEALLOCATE_PL_NATIVE(); + DEALLOCATE_PL_SIMPLE(); + DEALLOCATE_PL_WALK(); #if (TEST_GEOM_TRAITS == SEGMENT_GEOM_TRAITS) || \ (TEST_GEOM_TRAITS == LINEAR_GEOM_TRAITS) - if (m_lm_pl) { - delete m_lm_pl; - m_lm_pl = NULL; - } - if (m_random_lm_pl) { - delete m_random_lm_pl; - m_random_lm_pl = NULL; - } - if (m_grid_lm_pl) { - delete m_grid_lm_pl; - m_grid_lm_pl = NULL; - } - if (m_halton_lm_pl) { - delete m_halton_lm_pl; - m_halton_lm_pl = NULL; - } - if (m_middle_edges_lm_pl) { - delete m_middle_edges_lm_pl; - m_middle_edges_lm_pl = NULL; - } - if (m_specified_points_lm_pl) { - delete m_specified_points_lm_pl; - m_specified_points_lm_pl = NULL; - } - // Free Generators - if (m_random_g) { - delete m_random_g; - m_random_g = NULL; - } - if (m_grid_g) { - delete m_grid_g; - m_grid_g = NULL; - } - if (m_halton_g) { - delete m_halton_g; - m_halton_g = NULL; - } - if (m_middle_edges_g) { - delete m_middle_edges_g; - m_middle_edges_g = NULL; - } - if (m_specified_points_g) { - delete m_specified_points_g; - m_specified_points_g = NULL; - } + DEALLOCATE_PL_LM(); + DEALLOCATE_PL_LM_RANDOM(); + DEALLOCATE_PL_LM_GRID(); + DEALLOCATE_PL_LM_HALTON(); + DEALLOCATE_PL_LM_MIDDLE_EDGES(); + DEALLOCATE_PL_LM_SPECIFIED_POINTS(); + #endif #if (TEST_GEOM_TRAITS == SEGMENT_GEOM_TRAITS) - if (m_triangulation_pl) { - delete m_triangulation_pl; - m_triangulation_pl = NULL; - } + DEALLOCATE_PL_TRIANGULATION_PL(); #endif - if (m_trapezoid_ric_pl) { - delete m_trapezoid_ric_pl; - m_trapezoid_ric_pl = NULL; - } - if (m_trapezoid_ric_no_grnt_pl) { - delete m_trapezoid_ric_no_grnt_pl; - m_trapezoid_ric_no_grnt_pl = NULL; - } + DEALLOCATE_PL_TRAPEZOID_RIC_PL(); + DEALLOCATE_PL_TRAPEZOID_RIC_NO_GUARANTEE(); } -template -bool Point_location_test::allocate_arrangement() +template +bool Point_location_test::allocate_arrangement() { if (!(m_arr = new Arrangement(&m_geom_traits))) return false; return true; } -template -void Point_location_test:: +template +void Point_location_test:: deallocate_arrangement() { if (m_arr) { @@ -369,8 +793,8 @@ deallocate_arrangement() } } -template -bool Point_location_test:: +template +bool Point_location_test:: construct_arrangement() { // Insert all into the arrangement @@ -386,213 +810,118 @@ construct_arrangement() return true; } -template -void Point_location_test::clear_arrangement() -{ - if (m_arr) m_arr->clear(); -} +template +void Point_location_test::clear_arrangement() +{ if (m_arr) m_arr->clear(); } -template -bool Point_location_test:: -allocate_pl_strategies() +template +bool Point_location_test::allocate_pl_strategies() { // Allocate all point location strategies. - if (!(m_naive_pl = new Naive_point_location())) return false; - if (!(m_simple_pl = new Simple_point_location())) return false; - if (!(m_walk_pl = new Walk_point_location())) return false; + ALLOCATE_PL_NATIVE(); + ALLOCATE_PL_SIMPLE(); + ALLOCATE_PL_WALK(); #if (TEST_GEOM_TRAITS == SEGMENT_GEOM_TRAITS) || \ (TEST_GEOM_TRAITS == LINEAR_GEOM_TRAITS) - if (!(m_lm_pl = new Lm_point_location())) return false; - if (!(m_random_lm_pl = new Lm_random_point_location())) return false; - if (!(m_grid_lm_pl = new Lm_grid_point_location())) return false; - if (!(m_halton_lm_pl = new Lm_halton_point_location())) return false; - if (!(m_middle_edges_lm_pl = new Lm_middle_edges_point_location())) - return false; - if (!(m_specified_points_lm_pl = new Lm_specified_points_point_location())) - return false; + ALLOCATE_PL_LM(); + ALLOCATE_PL_LM_RANDOM(); + ALLOCATE_PL_LM_GRID(); + ALLOCATE_PL_LM_HALTON(); + ALLOCATE_PL_LM_MIDDLE_EDGES(); + ALLOCATE_PL_LM_SPECIFIED_POINTS(); + #endif #if (TEST_GEOM_TRAITS == SEGMENT_GEOM_TRAITS) - if (!(m_triangulation_pl = new Triangulation_point_location())) return false; + ALLOCATE_PL_TRIANGULATION_PL(); #endif - if (!(m_trapezoid_ric_pl = new Trapezoid_ric_point_location())) return false; - if (!(m_trapezoid_ric_no_grnt_pl = new Trapezoid_ric_point_location())) - return false; + ALLOCATE_PL_TRAPEZOID_RIC_PL(); + ALLOCATE_PL_TRAPEZOID_RIC_NO_GUARANTEE(); - // ===> Add new point location instance here. <=== return true; } -template -bool Point_location_test:: -construct_pl_strategies() +template +bool Point_location_test::construct_pl_strategies() { // Initialize all point location strategies. CGAL::Timer timer; - m_naive_pl = new Naive_point_location(*m_arr); // 0 - m_simple_pl = new Simple_point_location(*m_arr); // 1 - m_walk_pl = new Walk_point_location(*m_arr); // 2 + CONSTRUCT_PL_NATIVE(); + CONSTRUCT_PL_SIMPLE(); + CONSTRUCT_PL_WALK(); #if (TEST_GEOM_TRAITS == SEGMENT_GEOM_TRAITS) || \ (TEST_GEOM_TRAITS == LINEAR_GEOM_TRAITS) - timer.reset(); timer.start(); - m_lm_pl = new Lm_point_location(*m_arr); // 3 - timer.stop(); - std::cout << "Lm (vert) construction took " << timer.time() << std::endl; + MEASURE_LM_PL(timer, CONSTRUCT_PL_LM()); + MEASURE_LM_RANDOM_PL(timer, CONSTRUCT_PL_LM_RANDOM()); + MEASURE_LM_GRID_PL(timer, CONSTRUCT_PL_LM_GRID()); + MEASURE_LM_HALTON_PL(timer, CONSTRUCT_PL_LM_HALTON()); + MEASURE_LM_MIDDLE_EDGES_PL(timer, CONSTRUCT_PL_LM_MIDDLE_EDGES()); + MEASURE_LM_SPECIFIED_POINTS_PL(timer, CONSTRUCT_PL_LM_SPECIFIED_POINTS()); - timer.reset(); timer.start(); - m_random_g = new Random_lm_generator(*m_arr); - m_random_lm_pl = new Lm_random_point_location(*m_arr, m_random_g); // 4 - timer.stop(); - std::cout << "Random lm construction took " << timer.time() << std::endl; - - timer.reset(); timer.start(); - m_grid_g = new Grid_lm_generator(*m_arr); - m_grid_lm_pl = new Lm_grid_point_location(*m_arr, m_grid_g); // 5 - timer.stop(); - std::cout << "Grid lm construction took " << timer.time() << std::endl; - - timer.reset(); timer.start(); - m_halton_g = new Halton_lm_generator(*m_arr); - m_halton_lm_pl = new Lm_halton_point_location(*m_arr, m_halton_g); // 6 - timer.stop(); - std::cout << "Halton lm construction took " << timer.time() << std::endl; - - timer.reset(); timer.start(); - m_middle_edges_g = new Middle_edges_generator(*m_arr); - m_middle_edges_lm_pl = - new Lm_middle_edges_point_location(*m_arr, m_middle_edges_g); // 7 - timer.stop(); - std::cout << "Middle edges lm construction took " << timer.time() - << std::endl; - - timer.reset(); timer.start(); - m_specified_points_g = new Specified_points_generator(*m_arr); - m_specified_points_lm_pl = - new Lm_specified_points_point_location(*m_arr, m_specified_points_g); // 8 - timer.stop(); - std::cout << "Specified_points lm construction took " - << timer.time() << std::endl; #endif #if (TEST_GEOM_TRAITS == SEGMENT_GEOM_TRAITS) - timer.reset(); timer.start(); - m_triangulation_pl = new Triangulation_point_location(*m_arr); // 9 - timer.stop(); - std::cout << "Triangulation lm construction took " - << timer.time() << std::endl; + MEASURE_TRIANGULATION_PL(timer, CONSTRUCT_PL_TRIANGULATION_PL()); #endif - timer.reset(); timer.start(); - m_trapezoid_ric_pl = new Trapezoid_ric_point_location(*m_arr); // 10 - timer.stop(); - std::cout << "Trapezoid RIC construction took " << timer.time() << std::endl; - - timer.reset(); timer.start(); - m_trapezoid_ric_no_grnt_pl = - new Trapezoid_ric_point_location(*m_arr, false); // 11 - timer.stop(); - std::cout << "Trapezoid RIC without-guarantees construction took " - << timer.time() << std::endl; + MEASURE_TRAPEZOID_RIC_PL(timer, CONSTRUCT_PL_TRAPEZOID_RIC_PL()); + MEASURE_TRAPEZOID_RIC_NO_GUARANTEE_PL(timer, + CONSTRUCT_PL_TRAPEZOID_RIC_NO_GUARANTEE()); std::cout << std::endl; - // ===> Add new point location instance here. <=== return true; } -template -bool Point_location_test::attach_pl_strategies() +template +bool Point_location_test::attach_pl_strategies() { // Initialize all point location strategies. CGAL::Timer timer; - m_naive_pl->attach(*m_arr); - m_simple_pl->attach(*m_arr); - m_walk_pl->attach(*m_arr); + ATTACH_PL_NATIVE(); + ATTACH_PL_SIMPLE(); + ATTACH_PL_WALK(); #if (TEST_GEOM_TRAITS == SEGMENT_GEOM_TRAITS) || \ (TEST_GEOM_TRAITS == LINEAR_GEOM_TRAITS) - timer.reset(); timer.start(); - m_lm_pl->attach(*m_arr); - timer.stop(); - std::cout << "Lm (vert) construction took " << timer.time() << std::endl; - - timer.reset(); timer.start(); - m_random_g = new Random_lm_generator(*m_arr); - m_random_lm_pl->attach(*m_arr, m_random_g); - timer.stop(); - std::cout << "Random lm construction took " << timer.time() << std::endl; - - timer.reset(); timer.start(); - m_grid_g = new Grid_lm_generator(*m_arr); - m_grid_lm_pl->attach(*m_arr, m_grid_g); - timer.stop(); - std::cout << "Grid lm construction took " << timer.time() << std::endl; - - timer.reset(); timer.start(); - m_halton_g = new Halton_lm_generator(*m_arr); - m_halton_lm_pl->attach(*m_arr, m_halton_g); - timer.stop(); - std::cout << "Halton lm construction took " << timer.time() << std::endl; - - timer.reset(); timer.start(); - m_middle_edges_g = new Middle_edges_generator(*m_arr); - m_middle_edges_lm_pl->attach(*m_arr, m_middle_edges_g); - timer.stop(); - std::cout << "Middle edges lm construction took " << timer.time() - << std::endl; - - timer.reset(); timer.start(); - m_specified_points_g = new Specified_points_generator(*m_arr); - m_specified_points_lm_pl->attach(*m_arr, m_specified_points_g); - timer.stop(); - std::cout << "Specified_points lm construction took " - << timer.time() << std::endl; + MEASURE_LM_PL(timer, ATTACH_PL_LM()); + MEASURE_LM_RANDOM_PL(timer, ATTACH_PL_LM_RANDOM()); + MEASURE_LM_GRID_PL(timer, ATTACH_PL_LM_GRID()); + MEASURE_LM_HALTON_PL(timer, ATTACH_PL_LM_HALTON()); + MEASURE_LM_MIDDLE_EDGES_PL(timer, ATTACH_PL_LM_MIDDLE_EDGES()); + MEASURE_LM_SPECIFIED_POINTS_PL(timer, ATTACH_PL_LM_SPECIFIED_POINTS()); #endif #if (TEST_GEOM_TRAITS == SEGMENT_GEOM_TRAITS) - timer.reset(); timer.start(); - m_triangulation_pl->attach(*m_arr); - timer.stop(); - std::cout << "Triangulation lm construction took " - << timer.time() << std::endl; + MEASURE_TRIANGULATION_PL(timer, ATTACH_PL_TRIANGULATION_PL()); #endif - timer.reset(); timer.start(); - m_trapezoid_ric_pl->attach(*m_arr); - timer.stop(); - std::cout << "Trapezoid RIC construction took " << timer.time() << std::endl; - - timer.reset(); timer.start(); - m_trapezoid_ric_no_grnt_pl->with_guarantees(false); - m_trapezoid_ric_no_grnt_pl->attach(*m_arr); - - timer.stop(); - std::cout << "Trapezoid RIC without-guarantees construction took " - << timer.time() << std::endl; + MEASURE_TRAPEZOID_RIC_PL(timer, ATTACH_PL_TRAPEZOID_RIC_PL()); + MEASURE_TRAPEZOID_RIC_NO_GUARANTEE_PL(timer, + ATTACH_PL_TRAPEZOID_RIC_NO_GUARANTEE()); std::cout << std::endl; - // ===> Add new point location instance here. <=== return true; } // Perform the test -template -bool Point_location_test::perform() +template +bool Point_location_test::perform() { #if ((CGAL_ARR_POINT_LOCATION_VERSION < 2) || \ defined(CGAL_ARR_POINT_LOCATION_CONVERSION)) - Objects_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES]; + Objects_vector objs[NUM_PL_STRATEGIES]; #else - Variants_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES]; + Variants_vector objs[NUM_PL_STRATEGIES]; #endif // Locate the points in the list using all point location strategies. @@ -602,62 +931,30 @@ bool Point_location_test::perform() size_t pl_index = 0; - query(*m_naive_pl, "Naive", m_query_points.begin(), m_query_points.end(), - std::back_inserter(objs[pl_index++])); // Naive - - query(*m_simple_pl, "Simple", m_query_points.begin(), m_query_points.end(), - std::back_inserter(objs[pl_index++])); // Simple - - query(*m_walk_pl, "Walk", m_query_points.begin(), m_query_points.end(), - std::back_inserter(objs[pl_index++])); // Walk + QUERY_PL_NATIVE(objs[pl_index++]); + QUERY_PL_SIMPLE(objs[pl_index++]); + QUERY_PL_WALK(objs[pl_index++]); #if (TEST_GEOM_TRAITS == SEGMENT_GEOM_TRAITS) || \ (TEST_GEOM_TRAITS == LINEAR_GEOM_TRAITS) - query(*m_lm_pl, "Landmarks (vertices)", - m_query_points.begin(), m_query_points.end(), - std::back_inserter(objs[pl_index++])); // Landmarks (vertices) - - query(*m_random_lm_pl, "Landmarks random", - m_query_points.begin(), m_query_points.end(), - std::back_inserter(objs[pl_index++])); // Landmarks random - - query(*m_grid_lm_pl, "Landmarks grid", - m_query_points.begin(), m_query_points.end(), - std::back_inserter(objs[pl_index++])); // Landmarks grid - - query(*m_halton_lm_pl, "Landmarks Halton", - m_query_points.begin(), m_query_points.end(), - std::back_inserter(objs[pl_index++])); // Landmarks Halton - - query(*m_middle_edges_lm_pl, "Landmarks middle edges", - m_query_points.begin(), m_query_points.end(), - std::back_inserter(objs[pl_index++])); // Landmarks middle edges - - query(*m_specified_points_lm_pl, "Landmarks specified points", - m_query_points.begin(), m_query_points.end(), - std::back_inserter(objs[pl_index++])); // Landmarks specified points + QUERY_PL_LM(objs[pl_index++]); + QUERY_PL_LM_RANDOM(objs[pl_index++]); + QUERY_PL_LM_GRID(objs[pl_index++]); + QUERY_PL_LM_HALTON(objs[pl_index++]); + QUERY_PL_LM_MIDDLE_EDGES(objs[pl_index++]); + QUERY_PL_LM_SPECIFIED_POINTS(objs[pl_index++]); #endif #if (TEST_GEOM_TRAITS == SEGMENT_GEOM_TRAITS) - query(*m_triangulation_pl, "Triangulation", - m_query_points.begin(), m_query_points.end(), - std::back_inserter(objs[pl_index++])); // Triangulation + QUERY_PL_TRIANGULATION_PL(objs[pl_index++]); #endif - query(*m_trapezoid_ric_pl, "Trapezoidal RIC", - m_query_points.begin(), m_query_points.end(), - std::back_inserter(objs[pl_index++])); // Trapezoidal RIC - - // Trapezoidal RIC without guarantees - query(*m_trapezoid_ric_no_grnt_pl, "Trapezoidal RIC without guarantees", - m_query_points.begin(), m_query_points.end(), - std::back_inserter(objs[pl_index++])); + QUERY_PL_TRAPEZOID_RIC_PL(objs[pl_index++]); + QUERY_PL_TRAPEZOID_RIC_NO_GUARANTEE(objs[pl_index++]); std::cout << std::endl; - // ===> Add a call to operate the new point location. <=== - // Number of point location strategies used. size_t pls_num = pl_index; std::cout << "Number of strategies is " << pls_num << std::endl; @@ -683,11 +980,10 @@ bool Point_location_test::perform() return (result == 0); } -// Verify the results -template -int Point_location_test:: -verify(Objects_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES], - size_t size, size_t pls_num) +//! Verify the results +template +int Point_location_test:: +verify(Objects_vector objs[NUM_PL_STRATEGIES], size_t size, size_t pls_num) { Vertex_const_handle vh_ref, vh_cur; Halfedge_const_handle hh_ref, hh_cur; @@ -799,29 +1095,20 @@ verify(Objects_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES], } // Verify the results -template -int Point_location_test:: -verify(Variants_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES], - size_t size, size_t pls_num) +template +int Point_location_test:: +verify(Variants_vector objs[NUM_PL_STRATEGIES], size_t size, size_t pls_num) { - const Vertex_const_handle* vh_ref; - const Halfedge_const_handle* hh_ref; - const Face_const_handle* fh_ref; - - const Vertex_const_handle* vh_cur; - const Halfedge_const_handle* hh_cur; - const Face_const_handle* fh_cur; - int result = 0; // Assign and check results - size_t qi; //qi is the query point index - for (qi = 0; qi < size; ++qi) { + for (size_t qi = 0; qi < size; ++qi) { // Assign object to a face - fh_ref = boost::get(&(objs[0][qi])); + Face_const_handle* fh_ref = boost::get(&(objs[0][qi])); if (fh_ref) { for (size_t pl = 1; pl < pls_num; ++pl) { - fh_cur = boost::get(&(objs[pl][qi])); + Face_const_handle* fh_cur = + boost::get(&(objs[pl][qi])); if (fh_cur) { if ((*fh_cur) != (*fh_ref)) { std::cout << "Error: point location number " << pl << std::endl; @@ -835,12 +1122,14 @@ verify(Variants_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES], std::cout << "Error: point location number " << pl << std::endl; std::cout << "Expected: a face." << std::endl; result += -1; - hh_cur = boost::get(&(objs[pl][qi])); + Halfedge_const_handle* hh_cur = + boost::get(&(objs[pl][qi])); if (hh_cur) { std::cout << "Actual: a halfedge." << std::endl; continue; } - vh_cur = boost::get(&(objs[pl][qi])); + Vertex_const_handle* vh_cur = + boost::get(&(objs[pl][qi])); if (vh_cur) { std::cout << "Actual: a vertex." << std::endl; continue; @@ -855,10 +1144,12 @@ verify(Variants_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES], } // Assign object to a halfedge - hh_ref = boost::get(&(objs[0][qi])); + Halfedge_const_handle* hh_ref = + boost::get(&(objs[0][qi])); if (hh_ref) { for (size_t pl = 1; pl < pls_num; ++pl) { - hh_cur = boost::get(&(objs[pl][qi])); + Halfedge_const_handle* hh_cur = + boost::get(&(objs[pl][qi])); if (hh_cur) { if (((*hh_cur) != (*hh_ref)) && ((*hh_cur)->twin() != (*hh_ref))) { std::cout << "Error: point location number " << pl << std::endl; @@ -874,12 +1165,14 @@ verify(Variants_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES], std::cout << "Expected: a halfedge, " << (*hh_ref)->curve() << std::endl; result += -1; - fh_cur = boost::get(&(objs[pl][qi])); + Face_const_handle* fh_cur = + boost::get(&(objs[pl][qi])); if (fh_cur) { std::cout << "Actual: a face." << std::endl; continue; } - vh_cur = boost::get(&(objs[pl][qi])); + Vertex_const_handle* vh_cur = + boost::get(&(objs[pl][qi])); if (vh_cur) { std::cout << "Actual: a vertex." << std::endl; continue; @@ -890,10 +1183,12 @@ verify(Variants_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES], } // Assign object to a vertex - vh_ref = boost::get(&(objs[0][qi])); + Vertex_const_handle* vh_ref = + boost::get(&(objs[0][qi])); if (vh_ref) { for (size_t pl = 1; pl < pls_num; ++pl) { - vh_cur = boost::get(&(objs[pl][qi])); + Vertex_const_handle* vh_cur = + boost::get(&(objs[pl][qi])); if (vh_cur) { if ((*vh_cur) != (*vh_ref)) { std::cout << "Error: point location number " << pl << std::endl; @@ -908,12 +1203,14 @@ verify(Variants_vector objs[MAX_NUM_POINT_LOCATION_STRATEGIES], std::cout << "Error: point location number " << pl << std::endl; std::cout << "Expected: a vertex: "<< (*vh_ref)->point() << std::endl; result += -1; - fh_cur = boost::get(&(objs[pl][qi])); + Face_const_handle* fh_cur = + boost::get(&(objs[pl][qi])); if (fh_cur) { std::cout << "Actual: a face." << std::endl; continue; } - hh_cur = boost::get(&(objs[pl][qi])); + Halfedge_const_handle* hh_cur = + boost::get(&(objs[pl][qi])); if (hh_cur) { std::cout << "Actual: a halfedge." << std::endl; continue; diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/data/point_location/segments/ops/test11.txt b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/data/point_location/segments/ops/test11.txt new file mode 100644 index 00000000000..494bf6ff4e1 --- /dev/null +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/data/point_location/segments/ops/test11.txt @@ -0,0 +1,15 @@ +i 0 +i 1 +i 2 +i 3 +i 4 +i 5 +i 6 +i 7 +d 7 +d 6 +d 5 +d 4 +d 3 +d 2 +d 1 diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/data/point_location/segments/ops/test12.txt b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/data/point_location/segments/ops/test12.txt new file mode 100644 index 00000000000..5bd5550c751 --- /dev/null +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/data/point_location/segments/ops/test12.txt @@ -0,0 +1,4 @@ +i 0 +i 1 +d 1 +i 1 diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/data/point_location/segments/xcurves/test11.txt b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/data/point_location/segments/xcurves/test11.txt new file mode 100644 index 00000000000..c3c7ebf7d38 --- /dev/null +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/data/point_location/segments/xcurves/test11.txt @@ -0,0 +1,8 @@ +0 0 1 1 +1 1 2 2 +2 2 3 3 +3 3 4 4 +4 4 5 5 +5 5 6 6 +6 6 7 7 +7 7 8 8 diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_point_location_dynamic.segments.cmd b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_point_location_dynamic.segments.cmd index 1c22dfed49c..e5bc1f66d70 100644 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_point_location_dynamic.segments.cmd +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/test_point_location_dynamic.segments.cmd @@ -1 +1,3 @@ ./data/empty.zero ./data/point_location/segments/xcurves/test10.txt ./data/empty.zero ./data/point_location/segments/ops/test10.txt ./data/point_location/segments/queries/test10.txt +./data/empty.zero ./data/point_location/segments/xcurves/test11.txt ./data/empty.zero ./data/point_location/segments/ops/test11.txt ./data/point_location/segments/queries/test03.txt +./data/empty.zero ./data/point_location/segments/xcurves/test11.txt ./data/empty.zero ./data/point_location/segments/ops/test12.txt ./data/point_location/segments/queries/test03.txt diff --git a/BGL/doc/BGL/PackageDescription.txt b/BGL/doc/BGL/PackageDescription.txt index 6bc7a8df81d..d40b1ec6ecf 100644 --- a/BGL/doc/BGL/PackageDescription.txt +++ b/BGL/doc/BGL/PackageDescription.txt @@ -618,6 +618,9 @@ user might encounter. - `CGAL::is_quad()` - `CGAL::is_quad_mesh()` - `CGAL::is_isolated_quad()` +- `CGAL::is_valid_halfedge_graph()` +- `CGAL::is_valid_face_graph()` +- `CGAL::is_valid_polygon_mesh()` - `CGAL::is_tetrahedron()` - `CGAL::is_hexahedron()` diff --git a/BGL/examples/BGL_LCC/copy_lcc.cpp b/BGL/examples/BGL_LCC/copy_lcc.cpp index c2ec115e12d..0def9a59b53 100644 --- a/BGL/examples/BGL_LCC/copy_lcc.cpp +++ b/BGL/examples/BGL_LCC/copy_lcc.cpp @@ -2,8 +2,6 @@ #include #include -#include -#include #include diff --git a/BGL/examples/BGL_LCC/transform_iterator_lcc.cpp b/BGL/examples/BGL_LCC/transform_iterator_lcc.cpp index 1268d4d9d77..40f1f884fee 100644 --- a/BGL/examples/BGL_LCC/transform_iterator_lcc.cpp +++ b/BGL/examples/BGL_LCC/transform_iterator_lcc.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include diff --git a/BGL/include/CGAL/boost/graph/Euler_operations.h b/BGL/include/CGAL/boost/graph/Euler_operations.h index 56d92e979ee..109de182736 100644 --- a/BGL/include/CGAL/boost/graph/Euler_operations.h +++ b/BGL/include/CGAL/boost/graph/Euler_operations.h @@ -1020,40 +1020,33 @@ add_face_to_border(typename boost::graph_traits::halfedge_descriptor h1, * collapses an edge in a graph. * * \tparam Graph must be a model of `MutableFaceGraph` - * Let `v0` and `v1` be the source and target vertices, and let `e` and `e'` be the halfedges of edge `v0v1`. + * Let `h` be the halfedge of `e`, and let `v0` and `v1` be the source and target vertices of `h`. + * Let `p_h` and `p_o_h` be respectively the edges of `prev(h,g)` and `prev(opposite(h, g), g)`. + * Let `o_n_h` and `o_n_o_h` be respectively the edges of `opposite(next(h,g))` and `opposite(next(opposite(h, g), g))`. * - * For `e`, let `en` and `ep` be the next and previous - * halfedges, that is `en = next(e, g)`, `ep = prev(e, g)`, and let - * `eno` and `epo` be their opposite halfedges, that is - * `eno = opposite(en, g)` and `epo = opposite(ep, g)`. - * Analoguously, for `e'` define `en'`, `ep'`, `eno'`, and `epo'`. + * After the collapse of edge `e` the following holds: + * - The edge `e` is no longer in `g`. + * - The faces incident to edge `e` are no longer in `g`. + * - `v0` is no longer in `g`. + * - If `h` is not a border halfedge, `p_h` is no longer in `g` and is replaced by `o_n_h`. + * - If the opposite of `h` is not a border halfedge, `p_o_h` is no longer in `g` and is replaced by `o_n_o_h`. + * - The halfedges kept in `g` that had `v0` as target and source now have `v1` as target and source, respectively. + * - No other incidence information is changed in `g`. * - * Then, after the collapse of edge `v0v1` the following holds for `e` (and analoguously for `e'`) - * - *
    - *
  • The edge `v0v1` is no longer in `g`. - *
  • The faces incident to edge `v0v1` are no longer in `g`. - *
  • Either `v0`, or `v1` is no longer in `g` while the other remains. - * Let `vgone` be the removed vertex and `vkept` be the remaining vertex. - *
  • If `e` was a border halfedge, that is `is_border(e, g) == true`, then `next(ep,g) == en`, and `prev(en,g) == ep`. - *
  • If `e` was not a border halfedge, that is `is_border(e, g) == false`, then `ep` and `epo` are no longer in `g` while `en` and `eno` are kept in `g`. - *
  • For all halfedges `hv` in `halfedges_around_target(vgone, g)`, `target(*hv, g) == vkept` and `source(opposite(*hv, g), g) == vkept`. - *
  • No other incidence information has changed in `g`. - *
- * \returns vertex `vkept` (which can be either `v0` or `v1`). + * \returns vertex `v1`. * \pre g must be a triangulated graph - * \pre `does_satisfy_link_condition(v0v1,g) == true`. + * \pre `does_satisfy_link_condition(e,g) == true`. */ template typename boost::graph_traits::vertex_descriptor -collapse_edge(typename boost::graph_traits::edge_descriptor v0v1, +collapse_edge(typename boost::graph_traits::edge_descriptor e, Graph& g) { typedef boost::graph_traits< Graph > Traits; typedef typename Traits::vertex_descriptor vertex_descriptor; typedef typename Traits::halfedge_descriptor halfedge_descriptor; - halfedge_descriptor pq = halfedge(v0v1,g); + halfedge_descriptor pq = halfedge(e,g); halfedge_descriptor qp = opposite(pq, g); halfedge_descriptor pt = opposite(prev(pq, g), g); halfedge_descriptor qb = opposite(prev(qp, g), g); @@ -1068,51 +1061,9 @@ collapse_edge(typename boost::graph_traits::edge_descriptor v0v1, vertex_descriptor q = target(pq, g); vertex_descriptor p = source(pq, g); -#if 0 - if(lTopLeftFaceExists && lBottomRightFaceExists){ - std::cerr << " // do it low level" << std::endl; - halfedge_descriptor qt = next(pq,g); - halfedge_descriptor pb = next(qp,g); - halfedge_descriptor ppt = prev(pt,g); - halfedge_descriptor pqb = prev(qb,g); - if(halfedge(q,g) == pq){ - set_halfedge(q, pqb,g); - } - vertex_descriptor t = target(qt,g); - if(halfedge(t,g) == pt){ - set_halfedge(t, qt,g); - } - vertex_descriptor b = target(pb,g); - if(halfedge(b,g) == qb){ - set_halfedge(t, pb,g); - } - set_face(qt, face(pt,g),g); - set_halfedge(face(qt,g),qt,g); - set_face(pb, face(qb,g),g); - set_halfedge(face(pb,g),pb,g); - set_next(qt, next(pt,g),g); - set_next(pb, next(qb,g),g); - set_next(ppt, qt,g); - set_next(pqb,pb,g); - remove_face(face(pq,g),g); - remove_face(face(qp,g),g); - remove_edge(v0v1,g); - remove_edge(edge(pt,g),g); - remove_edge(edge(qb,g),g); - remove_vertex(p,g); - Halfedge_around_target_circulator beg(ppt,g), end(pqb,g); - while(beg != end){ - CGAL_assertion(target(*beg,g) == p); - set_target(*beg,q,g); - --beg; - } - return q; - // return the vertex kept - } -#endif - bool lP_Erased = false, lQ_Erased = false ; + bool lP_Erased = false; if ( lTopFaceExists ) { @@ -1137,7 +1088,7 @@ collapse_edge(typename boost::graph_traits::edge_descriptor v0v1, //CGAL_ECMS_TRACE(3, "Bottom face doesn't exist so vertex P already removed" ) ; lP_Erased = true ; - } + } } } @@ -1158,19 +1109,20 @@ collapse_edge(typename boost::graph_traits::edge_descriptor v0v1, // << q.idx() << "->V" << target(qb, g).idx() // << ") by erasing bottom face" ) ; - remove_face(opposite(qb, g),g); - if ( !lTopFaceExists ) { //CGAL_ECMS_TRACE(3, "Top face doesn't exist so vertex Q already removed" ) ; - lQ_Erased = true ; - } + lP_Erased = true ; + + // q will be removed, swap p and q + internal::swap_vertices(p, q, g); + } + + remove_face(opposite(qb, g),g); } } - CGAL_assertion( !lP_Erased || !lQ_Erased ) ; - - if ( !lP_Erased && !lQ_Erased ) + if ( !lP_Erased ) { //CGAL_ECMS_TRACE(3, "Removing vertex P by joining pQ" ) ; @@ -1178,21 +1130,24 @@ collapse_edge(typename boost::graph_traits::edge_descriptor v0v1, lP_Erased = true ; } - CGAL_expensive_assertion(is_valid(g)); + CGAL_expensive_assertion(is_valid_polygon_mesh(g)); - return lP_Erased ? q : p ; + return q; } /** - * Collapses the edge `v0v1` replacing it with v0 or v1, as described in the paragraph above + * collapses an edge in a graph having non-collapsable edges. + * + * Let `h` be the halfedge of `e`, and let `v0` and `v1` be the source and target vertices of `h`. + * Collapses the edge `e` replacing it with `v1`, as described in the paragraph above * and guarantees that an edge `e2`, for which `get(edge_is_constrained_map, e2)==true`, * is not removed after the collapse. * - * * \tparam Graph must be a model of `MutableFaceGraph` * \tparam EdgeIsConstrainedMap mut be a model of `ReadablePropertyMap` with the edge descriptor of `Graph` * as key type and a Boolean as value type. It indicates if an edge is constrained or not. * + * \returns vertex `v1`. * \pre This function requires `g` to be an oriented 2-manifold with or without boundaries. * Furthermore, the edge `v0v1` must satisfy the link condition, which guarantees that the surface mesh is also 2-manifold after the edge collapse. * \pre `get(edge_is_constrained_map, v0v1)==false`. @@ -1262,14 +1217,16 @@ collapse_edge(typename boost::graph_traits::edge_descriptor v0v1, { // the vertex is of valence 3 and we simply need to remove the vertex // and its indicent edges - bool lP_Erased = false; halfedge_descriptor edge = next(edges_to_erase[0],g) == edges_to_erase[1]? edges_to_erase[0]:edges_to_erase[1]; - if (target(edge,g) == p) - lP_Erased = true; + if (target(edge,g) != p) + { + // q will be removed, swap it with p + internal::swap_vertices(p, q, g); + } remove_center_vertex(edge,g); - return lP_Erased? q : p; + return q; } else { @@ -1294,19 +1251,29 @@ collapse_edge(typename boost::graph_traits::edge_descriptor v0v1, join_vertex(pq,g); return q; } - bool lQ_Erased = is_border(opposite(next(pq,g),g),g); + if( is_border(opposite(next(pq,g),g),g) ) + { + // q will be removed, swap it with p + internal::swap_vertices(p, q, g); + } remove_face(opposite(edges_to_erase[0],g),g); - return lQ_Erased?p:q; + return q; } if (! (is_border(edges_to_erase[0],g))){ + // q will be removed, swap it with p + internal::swap_vertices(p, q, g); join_face(edges_to_erase[0],g); join_vertex(qp,g); - return p; + return q; + } + if(!is_border(opposite(next(qp,g),g),g)) + { + // q will be removed, swap it with p + internal::swap_vertices(p, q, g); } - bool lP_Erased= is_border(opposite(next(qp,g),g),g); remove_face(opposite(edges_to_erase[0],g),g); - return lP_Erased?q:p; + return q; }; } diff --git a/BGL/include/CGAL/boost/graph/Graph_with_descriptor_with_graph.h b/BGL/include/CGAL/boost/graph/Graph_with_descriptor_with_graph.h index 11d5adeeb19..c51b4ebfaf1 100644 --- a/BGL/include/CGAL/boost/graph/Graph_with_descriptor_with_graph.h +++ b/BGL/include/CGAL/boost/graph/Graph_with_descriptor_with_graph.h @@ -153,7 +153,7 @@ struct Graph_with_descriptor_with_graph template -struct Descriptor2Descriptor: public CGAL::unary_function +struct Descriptor2Descriptor: public CGAL::cpp98::unary_function { Descriptor2Descriptor() @@ -691,7 +691,7 @@ template bool is_valid(const Graph_with_descriptor_with_graph & w, bool verbose = false) { - return is_valid(*w.graph,verbose); + return is_valid_polygon_mesh(*w.graph,verbose); } diff --git a/BGL/include/CGAL/boost/graph/graph_traits_OpenMesh.h b/BGL/include/CGAL/boost/graph/graph_traits_OpenMesh.h index bf95392fdb4..9c624d32537 100644 --- a/BGL/include/CGAL/boost/graph/graph_traits_OpenMesh.h +++ b/BGL/include/CGAL/boost/graph/graph_traits_OpenMesh.h @@ -34,7 +34,6 @@ #include #include - #if defined(BOOST_MSVC) # pragma warning(push) # pragma warning(disable:4267) @@ -622,12 +621,6 @@ add_face(OPEN_MESH_CLASS& sm) return sm.new_face(); } -template -bool is_valid(OPEN_MESH_CLASS& sm, bool /* verbose */ = false) -{ - return CGAL::is_valid_polygon_mesh(sm); -} - } // namespace OpenMesh namespace CGAL { diff --git a/BGL/include/CGAL/boost/graph/helpers.h b/BGL/include/CGAL/boost/graph/helpers.h index a4972113d60..f34e24b7687 100644 --- a/BGL/include/CGAL/boost/graph/helpers.h +++ b/BGL/include/CGAL/boost/graph/helpers.h @@ -29,6 +29,7 @@ #include #include #include +#include namespace CGAL { @@ -355,30 +356,292 @@ bool is_valid_face_descriptor( typename boost::graph_traits::face_des return true; } - -template -bool is_valid_polygon_mesh(const FaceGraph& g) +/*! + \ingroup PkgBGLHelperFct + * \brief checks the integrity of `g`. + * + * `g` is valid if it follows the rules of the `HalfedgeListGraph` concept, + * and all of its associations are reciprocal. + * For example, `prev(next(h, g), g)` must be `h`, + * and `next(prev(h, g), g)` must be `h`. + * \param g the `Graph` to test. + * \param verb : if `true`, the details of the check will be written in the standard output. + * + * \tparam `Graph` a model of `HalfedgeListGraph` + * \return `true` if `g` is valid, `false` otherwise. + * + */ +template +bool is_valid_halfedge_graph(const Graph& g, bool verb = false) { - typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename boost::graph_traits::face_descriptor face_descriptor; - BOOST_FOREACH(vertex_descriptor v, vertices(g)){ - if(! is_valid_vertex_descriptor(v,g)){ - return false; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::vertices_size_type vertex_size_type; + typedef typename boost::graph_traits::halfedges_size_type halfedges_size_type; + Verbose_ostream verr(verb); + std::size_t num_v(std::distance(boost::begin(vertices(g)), boost::end(vertices(g)))), + num_h(std::distance(boost::begin(halfedges(g)), boost::end(halfedges(g)))); + bool valid = ( 1 != (num_h& 1)); + if ( ! valid) + verr << "number of halfedges is odd." << std::endl; + + // All halfedges. + + halfedges_size_type n = 0; + BOOST_FOREACH(halfedge_descriptor begin, halfedges(g)) { + if(!valid) + break; + verr << "halfedge " << n << std::endl; + // Pointer integrity. + valid = valid && ( next(begin, g) != boost::graph_traits::null_halfedge()); + valid = valid && ( opposite(begin, g) != boost::graph_traits::null_halfedge()); + if ( ! valid) { + verr << " pointer integrity corrupted (ptr==0)." + << std::endl; + break; } - } - BOOST_FOREACH(halfedge_descriptor h, halfedges(g)){ - if(! is_valid_halfedge_descriptor(h,g)){ - return false; + //edge integrity + valid = valid && ( halfedge(edge(begin, g), g) == begin); + // opposite integrity. + valid = valid && ( opposite(begin, g) != begin); + valid = valid && ( opposite(opposite(begin, g), g) == begin); + if ( ! valid) { + verr << " opposite pointer integrity corrupted." + << std::endl; + break; } - } - BOOST_FOREACH(face_descriptor f, faces(g)){ - if(! is_valid_face_descriptor(f,g)){ - return false; + // previous integrity. + valid = valid && ( prev(next(begin, g), g) == begin); + valid = valid && ( next(prev(begin, g), g) == begin); + if ( ! valid) { + verr << " previous pointer integrity corrupted." + << std::endl; + break; } + // vertex integrity. + valid = valid && ( target(begin, g) != boost::graph_traits::null_vertex()); + if ( ! valid) { + verr << " vertex pointer integrity corrupted." + << std::endl; + break; + } + valid = valid && ( target(begin, g) == + target(opposite(next(begin, g), g), g)); + if ( ! valid) { + verr << " vertex pointer integrity2 corrupted." + << std::endl; + break; + } + + ++n; } - return true; + if ( valid && n != num_h) + verr << "counting halfedges failed." << std::endl; + // All vertices. + vertex_size_type v = 0; + n = 0; + BOOST_FOREACH(vertex_descriptor vbegin, vertices(g)){ + if(!valid) + break; + verr << "vertex " << v << std::endl; + // Pointer integrity. + if ( halfedge(vbegin, g) != boost::graph_traits::null_halfedge()) + valid = valid && ( + target( halfedge(vbegin, g), g) == vbegin); + else + valid = false; + if ( ! valid) { + verr << " halfedge pointer in vertex corrupted." + << std::endl; + break; + } + // cycle-around-vertex test. + halfedge_descriptor h = halfedge(vbegin, g); + if ( h != boost::graph_traits::null_halfedge()) { + halfedge_descriptor ge = h; + do { + verr << " halfedge " << n << std::endl; + ++n; + h = opposite(next(h, g), g); + valid = valid && ( n <= num_h && n!=0); + if ( ! valid) + verr << " too many halfedges around vertices." + << std::endl; + } while ( valid && (h != ge)); + } + ++v; + } + if ( valid && v != num_v) + verr << "counting vertices failed." << std::endl; + if ( valid && ( n != num_h)) + verr << "counting halfedges via vertices failed." << std::endl; + valid = valid && ( v == num_v); + + + // All halfedges. + n = 0; + BOOST_FOREACH(halfedge_descriptor i, halfedges(g)){ + verr << "halfedge " << n << std::endl; + // At least triangular facets and distinct geometry. + valid = valid && ( next(i, g) != i); + valid = valid && ( target(i, g) != target(opposite(i, g), g)); + if ( ! valid) { + verr << " pointer validity corrupted." + << std::endl; + break; + } + ++n; } +valid = valid && (n == num_h); +if ( n != num_h) + verr << "counting halfedges failed." << std::endl; + +verr << "structure is " + << ( valid ? "valid." : "NOT VALID.") << std::endl; +return valid; +} + +/*! + \ingroup PkgBGLHelperFct + * \brief checks the integrity of `g`. + * + * `g` is valid if it is a valid `HalfedgeListGraph`, if it follows the rules + * of the `FaceListGraph` concept, and all of its associations are reciprocal. + * For example, `face(halfedge(f,g),g)` must be `f`. + * calls `is_valid_halfedge_graph()` + * \param g the `Graph` to test. + * \param verb : if `true`, the details of the check will be written in the standard output. + * + * \tparam `Graph` a model of `FaceListGraph` + * \return `true` if `g` is valid, `false` otherwise. + * + * \see `is_valid_halfedge_graph()` + */ +template +bool is_valid_face_graph(const Graph& g, bool verb = false) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::graph_traits::faces_size_type faces_size_type; + typedef typename boost::graph_traits::halfedges_size_type halfedges_size_type; + std::size_t num_f(std::distance(boost::begin(faces(g)), boost::end(faces(g)))), + num_h(std::distance(boost::begin(halfedges(g)), boost::end(halfedges(g)))); + + //is valid halfedge_graph ? + bool valid=is_valid_halfedge_graph(g, verb); + if ( ! valid) { + return false; + } + Verbose_ostream verr(verb); + + // All faces. + faces_size_type f = 0; + std::size_t n = 0; + halfedges_size_type nb = 0; + BOOST_FOREACH(face_descriptor fbegin, faces(g)){ + if(!valid) + break; + verr << "face " << f << std::endl; + // Pointer integrity. + if ( halfedge(fbegin, g) != boost::graph_traits::null_halfedge()) + valid = valid && ( + face(halfedge(fbegin, g), g) == fbegin); + else + valid = false; + if ( ! valid) { + verr << " halfedge pointer in face corrupted." << std::endl; + break; + } + // cycle-around-face test. + halfedge_descriptor h = halfedge( fbegin, g); + if (h != boost::graph_traits::null_halfedge()) { + halfedge_descriptor ge = h; + do { + verr << " halfedge " << n << std::endl; + ++n; + h = next(h, g); + valid = valid && ( n <= num_h && n!=0); + if ( ! valid) + verr << " too many halfedges around faces." + << std::endl; + } while ( valid && (h != ge)); + } + ++f; + } + if ( valid && f != num_f) + verr << "counting faces failed." << std::endl; + + BOOST_FOREACH(halfedge_descriptor i, halfedges(g)){ + //counting borders + if ( is_border(i, g)) + ++nb; + // face integrity. + + valid = valid && ( face(i, g) == face(next(i, g), g)); + if ( ! valid) { + verr << " face pointer integrity2 corrupted." + << std::endl; + break; + } + } + verr << "sum border halfedges (2*nb) = " << 2 * nb << std::endl; + if ( valid && n + nb != num_h) + verr << "counting halfedges via faces failed." << std::endl; + valid = valid && ( f == num_f); + valid = valid && ( n + nb == num_h); + verr << "is_valid(): structure is " << ( valid ? "valid." : + "NOT VALID.") << std::endl; + return valid; +} +/*! + \ingroup PkgBGLHelperFct + * \brief checks the integrity of `g`. + * + * `g` is valid if it is a valid `FaceListGraph` and it has distinct faces on each side of an edge. + * calls `is_valid_face_graph()`. + * + * \param g the `Mesh` to test. + * \param verb : if `true`, the details of the check will be written in the standard output. + * + * \tparam Mesh a model of `FaceListGraph` and `HalfedgeListGraph`, and follows + * the definition of a \ref PMPDef "PolygonMesh" + * \return `true` if `g` is valid, `false` otherwise. + * + * \see `is_valid_face_graph()` + * \see `is_valid_halfedge_graph()` + * + */ +template +bool is_valid_polygon_mesh(const Mesh& g, bool verb = false) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + Verbose_ostream verr(verb); + bool valid=is_valid_face_graph(g, verb); + //test for 2-manifoldness + // Distinct facets on each side of an halfedge. + BOOST_FOREACH(halfedge_descriptor i, halfedges(g)){ + valid = valid && (face(i, g) != face(opposite(i, g), g)); + if ( ! valid) { + verr << " both incident facets are equal." << std::endl; + break; + } + valid = valid && ( next(next(i, g), g) != i); + valid = valid && ( target(i, g) != target(next(i, g), g)); + valid = valid && ( target(i, g) != target(next(next(i, g), g), g)); + if ( ! valid) { + verr << " incident facet is not at least a triangle." + << std::endl; + break; + } + if ( ! valid) { + verr << " incident facet is not at least a triangle." + << std::endl; + break; + } + } + return valid; +} + /*! \ingroup PkgBGLHelperFct @@ -1134,6 +1397,101 @@ clear_impl(FaceGraph& g) } } +template +void swap_vertices( + typename boost::graph_traits::vertex_descriptor& p, + typename boost::graph_traits::vertex_descriptor& q, + FaceGraph& g) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + + halfedge_descriptor hq=halfedge(q, g); + halfedge_descriptor hp=halfedge(p, g); + BOOST_FOREACH(halfedge_descriptor h, halfedges_around_target(hq, g)) + set_target(h, p, g); + BOOST_FOREACH(halfedge_descriptor h, halfedges_around_target(hp, g)) + set_target(h, q, g); + set_halfedge(p, hq, g); + set_halfedge(q, hp, g); +} + +template +void swap_edges( + const typename boost::graph_traits::halfedge_descriptor& h1, + const typename boost::graph_traits::halfedge_descriptor& h2, + FaceGraph& g) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + const halfedge_descriptor oh1 = opposite(h1, g), oh2 = opposite(h2, g); + + // backup vertex pointers + vertex_descriptor s1 = target(oh1, g), s2 = target(oh2, g); + vertex_descriptor t1 = target(h1, g), t2 = target(h2, g); + + // backup face pointers + face_descriptor f1 = face(h1, g), f2 = face(h2, g); + face_descriptor fo1 = face(oh1, g), fo2 = face(oh2, g); + + // backup next prev pointers + halfedge_descriptor nh1 = next(h1, g), nh2 = next(h2, g); + halfedge_descriptor ph1 = prev(h1, g), ph2 = prev(h2, g); + halfedge_descriptor noh1 = next(oh1, g), noh2 = next(oh2, g); + halfedge_descriptor poh1 = prev(oh1, g), poh2 = prev(oh2, g); + + // handle particular cases where next/prev are halfedges to be swapt + if (nh1 == oh2) nh1 = oh1; + if (nh1 == h2) nh1 = h1; + if (nh2 == oh1) nh2 = oh2; + if (nh2 == h1) nh2 = h2; + if (ph1 == oh2) ph1 = oh1; + if (ph1 == h2) ph1 = h1; + if (ph2 == oh1) ph2 = oh2; + if (ph2 == h1) ph2 = h2; + if (noh1 == oh2) noh1 = oh1; + if (noh1 == h2) noh1 = h1; + if (noh2 == oh1) noh2 = oh2; + if (noh2 == h1) noh2 = h2; + if (poh1 == oh2) poh1 = oh1; + if (poh1 == h2) poh1 = h1; + if (poh2 == oh1) poh2 = oh2; + if (poh2 == h1) poh2 = h2; + + // (1) exchange next pointers + set_next(h1, nh2, g); + set_next(h2, nh1, g); + set_next(ph1, h2, g); + set_next(ph2, h1, g); + set_next(oh1, noh2, g); + set_next(oh2, noh1, g); + set_next(poh1, oh2, g); + set_next(poh2, oh1, g); + + // (2) exchange vertex-halfedge pointers + set_target(h1, t2, g); + set_target(h2, t1, g); + set_target(oh1, s2, g); + set_target(oh2, s1, g); + if (halfedge(t1, g)==h1) set_halfedge(t1, h2, g); + if (halfedge(t2, g)==h2) set_halfedge(t2, h1, g); + if (halfedge(s1, g)==oh1) set_halfedge(s1, oh2, g); + if (halfedge(s2, g)==oh2) set_halfedge(s2, oh1, g); + + // (3) exchange face-halfedge pointers + set_face(h1, f2, g); + set_face(h2, f1, g); + set_face(oh1, fo2, g); + set_face(oh2, fo1, g); + + face_descriptor nf = boost::graph_traits::null_face(); + if (f1 != nf && halfedge(f1, g)==h1) set_halfedge(f1, h2, g); + if (f2 != nf && halfedge(f2, g)==h2) set_halfedge(f2, h1, g); + if (fo1 != nf && halfedge(fo1, g)==oh1) set_halfedge(fo1, oh2, g); + if (fo2 != nf && halfedge(fo2, g)==oh2) set_halfedge(fo2, oh1, g); +} + + } //end of internal namespace /** diff --git a/BGL/include/CGAL/boost/graph/parameters_interface.h b/BGL/include/CGAL/boost/graph/parameters_interface.h index fd75acf47d3..d152be492c8 100644 --- a/BGL/include/CGAL/boost/graph/parameters_interface.h +++ b/BGL/include/CGAL/boost/graph/parameters_interface.h @@ -46,6 +46,7 @@ CGAL_add_named_parameter(sparse_linear_solver_t, sparse_linear_solver, sparse_li CGAL_add_named_parameter(number_of_relaxation_steps_t, number_of_relaxation_steps, number_of_relaxation_steps) CGAL_add_named_parameter(protect_constraints_t, protect_constraints, protect_constraints) CGAL_add_named_parameter(relax_constraints_t, relax_constraints, relax_constraints) +CGAL_add_named_parameter(collapse_constraints_t, collapse_constraints, collapse_constraints) CGAL_add_named_parameter(vertex_is_constrained_t, vertex_is_constrained, vertex_is_constrained_map) CGAL_add_named_parameter(face_patch_t, face_patch, face_patch_map) CGAL_add_named_parameter(random_uniform_sampling_t, random_uniform_sampling, use_random_uniform_sampling) @@ -64,6 +65,7 @@ CGAL_add_named_parameter(nb_points_per_distance_unit_t, nb_points_per_distance_u CGAL_add_named_parameter(outward_orientation_t, outward_orientation, outward_orientation) CGAL_add_named_parameter(overlap_test_t, overlap_test, do_overlap_test_of_bounded_sides) CGAL_add_named_parameter(preserve_genus_t, preserve_genus, preserve_genus) +CGAL_add_named_parameter(projection_functor_t, projection_functor, projection_functor) // List of named parameters that we use in the package 'Surface Mesh Simplification' CGAL_add_named_parameter(get_cost_policy_t, get_cost_policy, get_cost) diff --git a/Mesh_3/include/CGAL/Mesh_3/global_parameters.h b/BGL/include/CGAL/boost/parameter.h similarity index 51% rename from Mesh_3/include/CGAL/Mesh_3/global_parameters.h rename to BGL/include/CGAL/boost/parameter.h index bde73012406..6413902f63e 100644 --- a/Mesh_3/include/CGAL/Mesh_3/global_parameters.h +++ b/BGL/include/CGAL/boost/parameter.h @@ -1,10 +1,9 @@ -// Copyright (c) 2009 INRIA Sophia-Antipolis (France). -// All rights reserved. +// Copyright (c) 2014 GeometryFactory (France). All rights reserved. // -// This file is part of CGAL (www.cgal.org). -// You can redistribute it and/or modify it under the terms of the GNU -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. @@ -14,23 +13,16 @@ // // $URL$ // $Id$ -// SPDX-License-Identifier: GPL-3.0+ +// SPDX-License-Identifier: LGPL-3.0+ +// // -// -// Author(s) : Stephane Tayeb -// -//****************************************************************************** -// File Description : -//****************************************************************************** - -#ifndef CGAL_MESH_3_GLOBAL_PARAMETERS_H -#define CGAL_MESH_3_GLOBAL_PARAMETERS_H - -#include +// Author(s) : Andreas Fabri +#ifndef CGAL_BOOST_PARAMETER_H +#define CGAL_BOOST_PARAMETER_H #include -#include + #ifdef BOOST_PARAMETER_MAX_ARITY # if (BOOST_PARAMETER_MAX_ARITY < 12) @@ -40,12 +32,31 @@ # define BOOST_PARAMETER_MAX_ARITY 12 #endif -#include +#include + +#if defined(__clang__) || (BOOST_GCC >= 40600) +# define CGAL_IGNORE_UNUSED_VARIABLES \ + _Pragma("GCC diagnostic ignored \"-Wunused-variable\"") \ + _Pragma("GCC diagnostic ignored \"-Wunused-parameter\"") +#else +# define CGAL_IGNORE_UNUSED_VARIABLES +#endif +#if __has_warning("-Wunneeded-internal-declaration") +# define CGAL_IGNORE_UNUSED_INTERNAL_DECLARATION \ + _Pragma("clang diagnostic ignored \"-Wunneeded-internal-declaration\"") +#else +# define CGAL_IGNORE_UNUSED_INTERNAL_DECLARATION +#endif + +#define CGAL_IGNORE_BOOST_PARAMETER_NAME_WARNINGS \ + CGAL_IGNORE_UNUSED_VARIABLES \ + CGAL_IGNORE_UNUSED_INTERNAL_DECLARATION -namespace CGAL { - -namespace parameters { +namespace CGAL +{ +namespace parameters +{ template struct Base @@ -56,33 +67,39 @@ private: T t_; }; -#define CGAL_MESH_BOOLEAN_PARAMETER(Class, function_true, function_false) \ +#define CGAL_BOOLEAN_PARAMETER(Class, function_true, function_false) \ struct Class : public Base { Class(bool b) : Base(b){} }; \ inline Class function_true() { return Class(true); } \ inline Class function_false() { return Class(false); } -#define CGAL_MESH_DOUBLE_PARAMETER(Class, function, precondition) \ +#define CGAL_DOUBLE_PARAMETER(Class, function, precondition) \ struct Class : public Base \ { Class(double d) : Base(d) { precondition(d); } }; \ inline Class function(double d) { return Class(d); } // see CGAL_PRAGMA_DIAG_PUSH -// see -CGAL_MESH_3_IGNORE_BOOST_PARAMETER_NAME_WARNINGS +// see +CGAL_IGNORE_BOOST_PARAMETER_NAME_WARNINGS BOOST_PARAMETER_NAME( c3t3 ) BOOST_PARAMETER_NAME( domain ) BOOST_PARAMETER_NAME( criteria ) - +BOOST_PARAMETER_NAME( cdt ) + +BOOST_PARAMETER_NAME( (seeds_begin, tag) seeds_begin_) +BOOST_PARAMETER_NAME( (seeds_end, tag) seeds_end_) +BOOST_PARAMETER_NAME( (mark, tag) mark_) + BOOST_PARAMETER_NAME( (time_limit, tag) time_limit_ ) +BOOST_PARAMETER_NAME( (convergence, tag) convergence_) +BOOST_PARAMETER_NAME( (max_iteration_number, tag) max_iteration_number_ ) +BOOST_PARAMETER_NAME( (freeze_bound, tag) freeze_bound_) + BOOST_PARAMETER_NAME( (sliver_bound, tag) sliver_bound_) BOOST_PARAMETER_NAME( (sliver_criterion, tag) sliver_criterion_) BOOST_PARAMETER_NAME( (perturbation_vector, tag) perturbation_vector_) -BOOST_PARAMETER_NAME( (freeze_bound, tag) freeze_bound_) BOOST_PARAMETER_NAME( (do_freeze, tag) do_freeze_) -BOOST_PARAMETER_NAME( (max_iteration_number, tag) max_iteration_number_ ) -BOOST_PARAMETER_NAME( (convergence, tag) convergence_) BOOST_PARAMETER_NAME( (mesh_topology, tag) mesh_topology_) @@ -96,13 +113,23 @@ BOOST_PARAMETER_NAME( (number_of_initial_points, tag) number_of_initial_points_) BOOST_PARAMETER_NAME( (maximal_number_of_vertices, tag ) maximal_number_of_vertices_) BOOST_PARAMETER_NAME( (pointer_to_error_code, tag ) pointer_to_error_code_) +// First used in +BOOST_PARAMETER_NAME( (function, tag ) function_) +BOOST_PARAMETER_NAME( (bounding_object, tag ) bounding_object_) +BOOST_PARAMETER_NAME( (relative_error_bound, tag ) relative_error_bound_) +BOOST_PARAMETER_NAME( (p_rng, tag ) p_rng_) +BOOST_PARAMETER_NAME( (null_subdomain_index, tag ) null_subdomain_index_) +BOOST_PARAMETER_NAME( (construct_surface_patch_index, tag ) construct_surface_patch_index_) + +// First used in +BOOST_PARAMETER_NAME( (image, tag ) image_) +BOOST_PARAMETER_NAME( (iso_value, tag) iso_value_) +BOOST_PARAMETER_NAME( (value_outside, tag) value_outside_) +BOOST_PARAMETER_NAME( (image_values_to_subdomain_indices, tag ) image_values_to_subdomain_indices_) + CGAL_PRAGMA_DIAG_POP -} // end namespace parameters +} // parameters +} // CGAL - - - -} //namespace CGAL - -#endif // CGAL_MESH_3_GLOBAL_PARAMETERS_H +#endif // CGAL_BOOST_PARAMETER_H diff --git a/BGL/test/BGL/CMakeLists.txt b/BGL/test/BGL/CMakeLists.txt index e3938cdd9c6..74efdb21fc3 100644 --- a/BGL/test/BGL/CMakeLists.txt +++ b/BGL/test/BGL/CMakeLists.txt @@ -98,6 +98,8 @@ create_single_source_cgal_program( "test_Face_filtered_graph.cpp" ) create_single_source_cgal_program( "test_Euler_operations.cpp" ) +create_single_source_cgal_program( "test_Collapse_edge.cpp" ) + create_single_source_cgal_program( "test_graph_traits.cpp" ) create_single_source_cgal_program( "test_Properties.cpp" ) @@ -105,6 +107,7 @@ create_single_source_cgal_program( "test_Properties.cpp" ) if(OpenMesh_FOUND) target_link_libraries( test_clear PRIVATE ${OPENMESH_LIBRARIES}) target_link_libraries( test_Euler_operations PRIVATE ${OPENMESH_LIBRARIES}) + target_link_libraries( test_Collapse_edge PRIVATE ${OPENMESH_LIBRARIES}) target_link_libraries( test_Face_filtered_graph PRIVATE ${OPENMESH_LIBRARIES}) target_link_libraries( test_graph_traits PRIVATE ${OPENMESH_LIBRARIES} ) target_link_libraries( test_Properties PRIVATE ${OPENMESH_LIBRARIES}) diff --git a/BGL/test/BGL/borders.cpp b/BGL/test/BGL/borders.cpp index e2c848718f9..4df20313137 100644 --- a/BGL/test/BGL/borders.cpp +++ b/BGL/test/BGL/borders.cpp @@ -2,8 +2,6 @@ #include #include -#include -#include #include #include #include diff --git a/BGL/test/BGL/data/flat_hexahedron.off b/BGL/test/BGL/data/flat_hexahedron.off new file mode 100644 index 00000000000..b7c3562356d --- /dev/null +++ b/BGL/test/BGL/data/flat_hexahedron.off @@ -0,0 +1,24 @@ +OFF +10 10 0 +-1.5 0 0 +-0.5 0 0 +0.5 0 0 +1.5 0 0 +-0.75 -0.5 0 +0 -0.5 0 +0.75 -0.5 0 +-0.75 0.5 0 +0 0.5 0 +0.75 0.5 0 + +3 0 1 7 +3 7 1 8 +3 8 1 2 +3 2 9 8 +3 9 2 3 + +3 0 4 1 +3 1 4 5 +3 1 5 2 +3 2 5 6 +3 2 6 3 diff --git a/BGL/test/BGL/graph_concept_Dual.cpp b/BGL/test/BGL/graph_concept_Dual.cpp index fc01a31ecae..6c29ab3fd57 100644 --- a/BGL/test/BGL/graph_concept_Dual.cpp +++ b/BGL/test/BGL/graph_concept_Dual.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff --git a/BGL/test/BGL/graph_concept_Gwdwg_Surface_mesh.cpp b/BGL/test/BGL/graph_concept_Gwdwg_Surface_mesh.cpp index 02a5b6cf1e7..3e8c442a57e 100644 --- a/BGL/test/BGL/graph_concept_Gwdwg_Surface_mesh.cpp +++ b/BGL/test/BGL/graph_concept_Gwdwg_Surface_mesh.cpp @@ -1,5 +1,4 @@ -#include -#include +#include #include #include diff --git a/BGL/test/BGL/graph_concept_Polyhedron_3.cpp b/BGL/test/BGL/graph_concept_Polyhedron_3.cpp index 00b9bd6103d..8a0d04458b1 100644 --- a/BGL/test/BGL/graph_concept_Polyhedron_3.cpp +++ b/BGL/test/BGL/graph_concept_Polyhedron_3.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff --git a/BGL/test/BGL/graph_concept_Seam_mesh_Surface_mesh.cpp b/BGL/test/BGL/graph_concept_Seam_mesh_Surface_mesh.cpp index 459b0709e92..222b683cd5f 100644 --- a/BGL/test/BGL/graph_concept_Seam_mesh_Surface_mesh.cpp +++ b/BGL/test/BGL/graph_concept_Seam_mesh_Surface_mesh.cpp @@ -1,5 +1,4 @@ -#include -#include +#include #include #include diff --git a/BGL/test/BGL/graph_concept_Surface_mesh.cpp b/BGL/test/BGL/graph_concept_Surface_mesh.cpp index dfeef4b03b6..1466fab4634 100644 --- a/BGL/test/BGL/graph_concept_Surface_mesh.cpp +++ b/BGL/test/BGL/graph_concept_Surface_mesh.cpp @@ -1,5 +1,4 @@ -#include -#include +#include #include #include diff --git a/BGL/test/BGL/test_Collapse_edge.cpp b/BGL/test/BGL/test_Collapse_edge.cpp new file mode 100644 index 00000000000..d1f9e0e22d8 --- /dev/null +++ b/BGL/test/BGL/test_Collapse_edge.cpp @@ -0,0 +1,226 @@ +#include "test_Prefix.h" +#include +#include + +template < typename Mesh> +typename boost::graph_traits:: +halfedge_descriptor find_halfedge(double x1, double y1, + double x2, double y2, + Mesh& m, + bool is_border = false) +{ + typedef typename boost::property_map::type VPMAP; + typedef typename boost::property_traits::value_type Point; + + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + VPMAP vpmap = get(CGAL::vertex_point, m); + BOOST_FOREACH(halfedge_descriptor h, halfedges(m)) + { + if(get(vpmap, source(h, m)) == Point(x1,y1,0) + && get(vpmap, target(h, m)) == Point(x2,y2,0)) + { + if(is_border == CGAL::is_border(h, m)) + return h; + else + return opposite(h, m); + } + } + return boost::graph_traits::null_halfedge(); +} + +template +void +collapse_edge_test() +{ + CGAL_GRAPH_TRAITS_MEMBERS(Mesh); + typedef typename boost::graph_traits:: vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits:: halfedge_descriptor halfedge_descriptor; + + const std::string fname = "data/flat_hexahedron.off"; + Mesh m; + if(!CGAL::read_off(fname, m)) { + std::cout << "Error reading file: " << fname << std::endl; + } + bool m_is_valid = CGAL::is_valid(m); + assert(m_is_valid); + + Mesh test_mesh; + CGAL::copy_face_graph(m, test_mesh); + m_is_valid = CGAL::is_valid(m); + assert(m_is_valid); + + //case 1: General Case. + { + halfedge_descriptor he = find_halfedge(-0.5,0, + 0.5,0, + test_mesh); + halfedge_descriptor en = next(he, test_mesh); + halfedge_descriptor eno = opposite(en, test_mesh); + halfedge_descriptor eno_prime = opposite(next(opposite(he, test_mesh), test_mesh), test_mesh); + vertex_descriptor v1 = target(he, test_mesh); + bool ok = CGAL::Euler::collapse_edge(edge(he, test_mesh), test_mesh) == v1; + assert(ok); + char found = 0; + BOOST_FOREACH(halfedge_descriptor it, CGAL::halfedges_around_target(v1,test_mesh)) + { + if(it == eno + || it == eno_prime){ + ++found; + } + } + assert(found == 2); + CGAL::clear(test_mesh); + + } + //case 2: collapsing edge is not itself a border, but is incident upon a border edge that is removed. + { + CGAL::copy_face_graph(m, test_mesh); + halfedge_descriptor he = find_halfedge(0,0.5, + -0.75,0.5, + test_mesh); + CGAL::Euler::remove_face(he, test_mesh); + + he = find_halfedge(-0.5,0, + 0.5,0, + test_mesh); + halfedge_descriptor en = next(he, test_mesh); + halfedge_descriptor eno = opposite(en, test_mesh); + halfedge_descriptor eno_prime = opposite(next(opposite(he, test_mesh), test_mesh), test_mesh); + vertex_descriptor v1 = target(he, test_mesh); + bool ok = CGAL::Euler::collapse_edge(edge(he, test_mesh), test_mesh) == v1; + assert(ok); + char found = 0; + BOOST_FOREACH(halfedge_descriptor it, CGAL::halfedges_around_target(v1,test_mesh)) + { + if(it == eno + || it == eno_prime){ + ++found; + } + } + assert(found == 2); + CGAL::clear(test_mesh); + } + //case 3: collapsing edge is not itself a border, but is incident upon a border edge that is not removed + { + CGAL::copy_face_graph(m, test_mesh); + halfedge_descriptor he = find_halfedge(1.5,0, + 0.75,0.5, + test_mesh); + CGAL::Euler::remove_face(he, test_mesh); + + he = find_halfedge(-0.5,0, + 0.5,0, + test_mesh); + halfedge_descriptor en = next(he, test_mesh); + halfedge_descriptor eno = opposite(en, test_mesh); + halfedge_descriptor eno_prime = opposite(next(opposite(he, test_mesh), test_mesh), test_mesh); + vertex_descriptor v1 = target(he, test_mesh); + bool ok = CGAL::Euler::collapse_edge(edge(he, test_mesh), test_mesh) == v1; + assert(ok); + char found = 0; + BOOST_FOREACH(halfedge_descriptor it, CGAL::halfedges_around_target(v1,test_mesh)) + { + if(it == eno + || it == eno_prime){ + ++found; + } + } + assert(found == 2); + CGAL::clear(test_mesh); + } + //case 4: collapsing edge is itself a border + { + CGAL::copy_face_graph(m, test_mesh); + halfedge_descriptor he = find_halfedge(-0.5, 0, + 0, -0.5, + test_mesh); + CGAL::Euler::remove_face(he, test_mesh); + he = find_halfedge(0, -0.5, + -0.5, 0, + test_mesh); + CGAL::Euler::remove_face(he, test_mesh); + he = find_halfedge(0, -0.5, + 0.75, -0.5, + test_mesh); + CGAL::Euler::remove_face(he, test_mesh); + + + he = find_halfedge(-0.5,0, + 0.5,0, + test_mesh); + halfedge_descriptor en = next(he, test_mesh); + halfedge_descriptor eno = opposite(en, test_mesh); + halfedge_descriptor ep_prime = prev(opposite(he, test_mesh), test_mesh); + halfedge_descriptor eno_prime = opposite(next(opposite(he, test_mesh), test_mesh), test_mesh); + vertex_descriptor v1 = target(he, test_mesh); + bool ok = CGAL::Euler::collapse_edge(edge(he, test_mesh), test_mesh) == v1; + assert(ok); + char found = 0; + BOOST_FOREACH(halfedge_descriptor it, CGAL::halfedges_around_target(v1,test_mesh)) + { + if(it == eno + || it == eno_prime + || it == ep_prime){ + ++found; + } + } + assert(found == 3); + CGAL::clear(test_mesh); + } + //case 5 singular case. + { + CGAL::copy_face_graph(m, test_mesh); + halfedge_descriptor he = find_halfedge(0.75,0.5, + 1.5,0, + test_mesh); + CGAL::Euler::remove_face(he, test_mesh); + he = find_halfedge(0.75,-0.5, + 1.5,0, + test_mesh); + CGAL::Euler::remove_face(he, test_mesh); + he = find_halfedge(0,0.5, + 0.5,0, + test_mesh); + CGAL::Euler::remove_face(he, test_mesh); + he = find_halfedge(0.5,0, + 0,-0.5, + test_mesh); + CGAL::Euler::remove_face(he, test_mesh); + + he = find_halfedge(-0.5,0, + 0.5,0, + test_mesh); + CGAL::Euler::remove_face(he, test_mesh); + halfedge_descriptor ep = prev(he, test_mesh); + halfedge_descriptor eno_prime = opposite(next(opposite(he, test_mesh), test_mesh), test_mesh); + vertex_descriptor v1 = target(he, test_mesh); + bool ok = CGAL::Euler::collapse_edge(edge(he, test_mesh), test_mesh) == v1; + assert(ok); + char found = 0; + BOOST_FOREACH(halfedge_descriptor it, CGAL::halfedges_around_target(v1,test_mesh)) + { + if(it == ep) + ++found; + else if( it == eno_prime){ + ++found; + } + } + assert(found == 2); + CGAL::clear(test_mesh); + } +} + + +int main() +{ + + collapse_edge_test(); + collapse_edge_test(); + +#ifdef CGAL_USE_OPENMESH + collapse_edge_test(); +#endif + + std::cerr << "done\n"; + return 0; +} diff --git a/BGL/test/BGL/test_Euler_operations.cpp b/BGL/test/BGL/test_Euler_operations.cpp index 616ea782b3f..3ae73d6c38d 100644 --- a/BGL/test/BGL/test_Euler_operations.cpp +++ b/BGL/test/BGL/test_Euler_operations.cpp @@ -41,7 +41,7 @@ join_face_test() assert(degree(f.w, f.m) == 2); assert(degree(f.v, f.m) == 3); - assert(CGAL::is_valid(f.m)); + assert(CGAL::is_valid_polygon_mesh(f.m)); } @@ -63,7 +63,7 @@ remove_face_test_1() CGAL::Euler::remove_face(e,f.m); - assert(CGAL::is_valid(f.m)); + assert(CGAL::is_valid_polygon_mesh(f.m)); assert_EQUAL(degree(f.v, f.m) == 3); assert_EQUAL(degree(f.x, f.m) == 2); @@ -99,7 +99,7 @@ remove_face_test_2() assert(found); assert(face(e, f.m) == f.f1); CGAL::Euler::remove_face(e,f.m); - assert(CGAL::is_valid(f.m)); + assert(CGAL::is_valid_polygon_mesh(f.m)); assert(CGAL::internal::exact_num_faces(f.m) == 3); assert(CGAL::internal::exact_num_edges(f.m) == 7); @@ -128,7 +128,7 @@ add_face_to_border_test() CGAL::Euler::add_face_to_border(f.h1, f.h2, f.m); - assert(CGAL::is_valid(f.m)); + assert(CGAL::is_valid_polygon_mesh(f.m)); } @@ -158,7 +158,7 @@ add_vertex_and_face_to_border_test() } halfedge_descriptor res = CGAL::Euler::add_vertex_and_face_to_border(f.h1, f.h2, f.m); - assert(CGAL::is_valid(f.m)); + assert(CGAL::is_valid_polygon_mesh(f.m)); assert(! CGAL::is_border(res,m)); assert(CGAL::is_border(opposite(res,m),m)); @@ -169,8 +169,6 @@ add_vertex_and_face_to_border_test() } assert(blength == 0); - - } @@ -193,7 +191,7 @@ join_vertex_interior_test() assert(boost::distance(CGAL::halfedges_around_face(halfedge(f.f1, f.m), f.m)) == 3); assert(boost::distance(CGAL::halfedges_around_face(halfedge(f.f2, f.m), f.m)) == 3); assert(degree(f.x, f.m) == 4); - assert(CGAL::is_valid(f.m)); + assert(CGAL::is_valid_polygon_mesh(f.m)); } template @@ -218,7 +216,7 @@ join_vertex_exterior_test() assert(boost::distance(CGAL::halfedges_around_face(halfedge(f.f1, f.m), f.m)) == 4); assert(boost::distance(CGAL::halfedges_around_face(halfedge(f.f2, f.m), f.m)) == 3); assert(degree(f.y, f.m) == 3); - assert(CGAL::is_valid(f.m)); + assert(CGAL::is_valid_polygon_mesh(f.m)); } { @@ -237,7 +235,7 @@ join_vertex_exterior_test() assert(boost::distance(CGAL::halfedges_around_face(halfedge(f.f1, f.m), f.m)) == 4); assert(boost::distance(CGAL::halfedges_around_face(halfedge(f.f2, f.m), f.m)) == 3); - assert(CGAL::is_valid(f.m)); + assert(CGAL::is_valid_polygon_mesh(f.m)); assert(degree(f.w, f.m) == 3); } @@ -261,7 +259,7 @@ split_vertex() // split border vertex y CGAL::Euler::split_vertex(h1, h2,f.m); - assert(CGAL::is_valid(f.m)); + assert(CGAL::is_valid_polygon_mesh(f.m)); assert(CGAL::internal::exact_num_vertices(f.m) == 7); assert(CGAL::internal::exact_num_edges(f.m) == 8); assert(boost::distance(CGAL::halfedges_around_face(h1, f.m)) == 5); @@ -279,13 +277,13 @@ split_join_vertex_inverse() boost::tie(h, found) = halfedge(f.w, f.x, f.m); assert(found); CGAL::Euler::join_vertex(h,f.m); - assert(CGAL::is_valid(f.m)); + assert(CGAL::is_valid_polygon_mesh(f.m)); boost::tie(h1, found) = halfedge(f.z, f.x, f.m); assert(found); boost::tie(h2, found) = halfedge(f.v, f.x, f.m); assert(found); CGAL::Euler::join_vertex(CGAL::Euler::split_vertex(h1, h2,f.m),f.m); - assert(CGAL::is_valid(f.m)); + assert(CGAL::is_valid_polygon_mesh(f.m)); assert(CGAL::internal::exact_num_vertices(f.m)== 5); assert(CGAL::internal::exact_num_faces(f.m) == 2); @@ -305,7 +303,7 @@ join_loop_test() CGAL::Euler::join_loop(f.h1, f.h2, f.m); - assert(CGAL::is_valid(f.m)); + assert(CGAL::is_valid_polygon_mesh(f.m)); } template @@ -319,7 +317,7 @@ split_loop_test() assert(CGAL::internal::exact_num_vertices(f.m) == 8); assert(CGAL::internal::exact_num_faces(f.m) == 8); assert(CGAL::internal::exact_num_halfedges(f.m) == 24); - assert(CGAL::is_valid(f.m)); + assert(CGAL::is_valid_polygon_mesh(f.m)); } template @@ -382,7 +380,27 @@ does_satisfy_link_condition() assert(CGAL::Euler::does_satisfy_link_condition(*edges(f.m).first,f.m)); } - +template +void +test_swap_edges() +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + std::size_t nbh=12; + Kernel::Point_3 pt(0,0,0); + // test all possible pairs of halfedges + for (std::size_t i=0; i void @@ -402,6 +420,7 @@ test_Euler_operations() remove_center_vertex_test(); join_split_inverse(); does_satisfy_link_condition(); + test_swap_edges(); } int main() diff --git a/BGL/test/BGL/test_Face_filtered_graph.cpp b/BGL/test/BGL/test_Face_filtered_graph.cpp index 75427a24292..5446a660266 100644 --- a/BGL/test/BGL/test_Face_filtered_graph.cpp +++ b/BGL/test/BGL/test_Face_filtered_graph.cpp @@ -272,7 +272,7 @@ void test_read(const Graph& g) std::map map; CGAL::Polygon_mesh_processing::connected_components(g, boost::make_assoc_property_map(map), CGAL::Polygon_mesh_processing::parameters::all_default()); Adapter fg(g, 0, boost::make_assoc_property_map(map)); - assert(CGAL::is_valid(fg)); + assert(CGAL::is_valid_polygon_mesh(fg)); } template @@ -357,7 +357,7 @@ void test_mesh(Adapter fga) CGAL_GRAPH_TRAITS_MEMBERS(Adapter); //check that there is the right number of simplices in fga - CGAL_assertion(CGAL::is_valid(fga)); + CGAL_assertion(CGAL::is_valid_polygon_mesh(fga)); CGAL_assertion(num_faces(fga) == 2); CGAL_assertion(num_edges(fga) == 5); CGAL_assertion(num_halfedges(fga) == 10); diff --git a/BGL/test/BGL/test_Manifold_face_removal.cpp b/BGL/test/BGL/test_Manifold_face_removal.cpp index adc6f3bbe49..f84b63175d5 100644 --- a/BGL/test/BGL/test_Manifold_face_removal.cpp +++ b/BGL/test/BGL/test_Manifold_face_removal.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include @@ -56,7 +55,7 @@ int main() } assert(index == 25); - assert(is_valid(sm)); + assert(is_valid_polygon_mesh(sm)); return 0; } diff --git a/BGL/test/BGL/test_Prefix.h b/BGL/test/BGL/test_Prefix.h index a06a1381bec..8aacfd12f99 100644 --- a/BGL/test/BGL/test_Prefix.h +++ b/BGL/test/BGL/test_Prefix.h @@ -157,7 +157,7 @@ template struct Surface_fixture_1 { Surface_fixture_1() { assert(read_a_mesh(m, "data/fixture1.off")); - assert(CGAL::is_valid(m)); + assert(CGAL::is_valid_polygon_mesh(m)); typename boost::property_map::const_type pm = get(CGAL::vertex_point, const_cast(m)); @@ -206,7 +206,7 @@ template struct Surface_fixture_2 { Surface_fixture_2() { assert(read_a_mesh(m, "data/fixture2.off")); - assert(CGAL::is_valid(m)); + assert(CGAL::is_valid_polygon_mesh(m)); typename boost::property_map::const_type pm = get(CGAL::vertex_point, const_cast(m)); @@ -267,7 +267,7 @@ template struct Surface_fixture_3 { Surface_fixture_3() { assert(read_a_mesh(m, "data/fixture3.off")); - assert(CGAL::is_valid(m)); + assert(CGAL::is_valid_polygon_mesh(m)); typename boost::property_map::const_type pm = get(CGAL::vertex_point, const_cast(m)); @@ -313,7 +313,7 @@ template struct Surface_fixture_4 { Surface_fixture_4() { assert(read_a_mesh(m, "data/fixture4.off")); - assert(CGAL::is_valid(m)); + assert(CGAL::is_valid_polygon_mesh(m)); typename boost::property_map::const_type pm = get(CGAL::vertex_point, const_cast(m)); @@ -348,7 +348,7 @@ template struct Surface_fixture_5 { Surface_fixture_5() { assert(read_a_mesh(m, "data/add_face_to_border.off")); - assert(CGAL::is_valid(m)); + assert(CGAL::is_valid_polygon_mesh(m)); typename boost::property_map::const_type pm = get(CGAL::vertex_point, const_cast(m)); @@ -378,7 +378,7 @@ template struct Surface_fixture_6 { Surface_fixture_6() { assert(read_a_mesh(m, "data/quad.off")); - assert(CGAL::is_valid(m)); + assert(CGAL::is_valid_polygon_mesh(m)); typename boost::graph_traits::halfedge_descriptor h; @@ -397,7 +397,7 @@ template struct Surface_fixture_7 { Surface_fixture_7() { assert(read_a_mesh(m, "data/cube.off")); - assert(CGAL::is_valid(m)); + assert(CGAL::is_valid_polygon_mesh(m)); h = *(halfedges(m).first); } @@ -410,7 +410,7 @@ template struct Surface_fixture_8 { Surface_fixture_8() { assert(read_a_mesh(m, "data/fixture5.off")); - assert(CGAL::is_valid(m)); + assert(CGAL::is_valid_polygon_mesh(m)); typename boost::property_map::const_type pm = get(CGAL::vertex_point, const_cast(m)); diff --git a/BGL/test/BGL/test_bgl_read_write.cpp b/BGL/test/BGL/test_bgl_read_write.cpp index bbbb1c4dbb7..894b772a610 100644 --- a/BGL/test/BGL/test_bgl_read_write.cpp +++ b/BGL/test/BGL/test_bgl_read_write.cpp @@ -1,10 +1,9 @@ #include #include -#include #include -#include +#include #include #include diff --git a/BGL/test/BGL/test_cgal_bgl_named_params.cpp b/BGL/test/BGL/test_cgal_bgl_named_params.cpp index 91cd3c5ff4a..fd1f631ea6b 100644 --- a/BGL/test/BGL/test_cgal_bgl_named_params.cpp +++ b/BGL/test/BGL/test_cgal_bgl_named_params.cpp @@ -57,6 +57,7 @@ void test(const NamedParameters& np) assert(get_param(np, CGAL::internal_np::number_of_relaxation_steps).v == 16); assert(get_param(np, CGAL::internal_np::protect_constraints).v == 17); assert(get_param(np, CGAL::internal_np::relax_constraints).v == 18); + assert(get_param(np, CGAL::internal_np::collapse_constraints).v == 43); assert(get_param(np, CGAL::internal_np::vertex_is_constrained).v == 19); assert(get_param(np, CGAL::internal_np::face_patch).v == 20); assert(get_param(np, CGAL::internal_np::random_uniform_sampling).v == 21); @@ -86,6 +87,7 @@ void test(const NamedParameters& np) assert(get_param(np, CGAL::internal_np::weight_calculator).v == 39); assert(get_param(np, CGAL::internal_np::preserve_genus).v == 40); assert(get_param(np, CGAL::internal_np::verbosity_level).v == 41); + assert(get_param(np, CGAL::internal_np::projection_functor).v == 42); // Test types @@ -121,6 +123,7 @@ void test(const NamedParameters& np) check_same_type<16>(get_param(np, CGAL::internal_np::number_of_relaxation_steps)); check_same_type<17>(get_param(np, CGAL::internal_np::protect_constraints)); check_same_type<18>(get_param(np, CGAL::internal_np::relax_constraints)); + check_same_type<43>(get_param(np, CGAL::internal_np::collapse_constraints)); check_same_type<19>(get_param(np, CGAL::internal_np::vertex_is_constrained)); check_same_type<20>(get_param(np, CGAL::internal_np::face_patch)); check_same_type<21>(get_param(np, CGAL::internal_np::random_uniform_sampling)); @@ -150,6 +153,7 @@ void test(const NamedParameters& np) check_same_type<39>(get_param(np, CGAL::internal_np::weight_calculator)); check_same_type<40>(get_param(np, CGAL::internal_np::preserve_genus)); check_same_type<41>(get_param(np, CGAL::internal_np::verbosity_level)); + check_same_type<42>(get_param(np, CGAL::internal_np::projection_functor)); } int main() @@ -176,6 +180,7 @@ int main() .number_of_relaxation_steps(A<16>(16)) .protect_constraints(A<17>(17)) .relax_constraints(A<18>(18)) + .collapse_constraints(A<43>(43)) .vertex_is_constrained_map(A<19>(19)) .face_patch_map(A<20>(20)) .use_random_uniform_sampling(A<21>(21)) @@ -199,6 +204,7 @@ int main() .weight_calculator(A<39>(39)) .preserve_genus(A<40>(40)) .verbosity_level(A<41>(41)) + .projection_functor(A<42>(42)) ); return EXIT_SUCCESS; diff --git a/BGL/test/BGL/test_circulator.cpp b/BGL/test/BGL/test_circulator.cpp index ce2b1a7fb8e..8cd8ac1e6ec 100644 --- a/BGL/test/BGL/test_circulator.cpp +++ b/BGL/test/BGL/test_circulator.cpp @@ -1,7 +1,5 @@ #include #include -#include -#include #include #include diff --git a/BGL/test/BGL/test_clear.cpp b/BGL/test/BGL/test_clear.cpp index eb733d748d4..05c8670a972 100644 --- a/BGL/test/BGL/test_clear.cpp +++ b/BGL/test/BGL/test_clear.cpp @@ -10,13 +10,13 @@ void test() { std::cout << "Error reading file: " << fname << std::endl; } - assert(CGAL::is_valid(m)); + assert(CGAL::is_valid_polygon_mesh(m)); CGAL::clear(m); assert(num_vertices(m) == 0); assert(num_faces(m) == 0); assert(num_edges(m) == 0); - assert(CGAL::is_valid(m)); + assert(CGAL::is_valid_polygon_mesh(m)); } int main() diff --git a/BGL/test/BGL/test_graph_traits.cpp b/BGL/test/BGL/test_graph_traits.cpp index 6024ec4782a..3224d91c010 100644 --- a/BGL/test/BGL/test_graph_traits.cpp +++ b/BGL/test/BGL/test_graph_traits.cpp @@ -254,9 +254,10 @@ void test_faces(const G& g) template void test_read(const G& g) { - assert(CGAL::is_valid(g)); + assert(CGAL::is_valid_polygon_mesh(g)); } + template void test(const std::vector& graphs) diff --git a/BGL/test/BGL/test_helpers.cpp b/BGL/test/BGL/test_helpers.cpp index e59447e3837..e4d0e145829 100644 --- a/BGL/test/BGL/test_helpers.cpp +++ b/BGL/test/BGL/test_helpers.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -25,9 +26,85 @@ test(const char *fname, bool triangle, bool quad, bool tetrahedron, bool hexahed assert(CGAL::is_hexahedron(hd, m) == hexahedron); } +template +void +test_validity(Mesh& mesh) +{ + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::edge_descriptor edge_descriptor; + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::property_map::type VPMap; + VPMap vpmap = get(CGAL::vertex_point, mesh); + vertex_descriptor vertices[4]; + edge_descriptor edges[4]; + vertices[0] = add_vertex(mesh); + vertices[1] = add_vertex(mesh); + vertices[2] = add_vertex(mesh); + vertices[3] = add_vertex(mesh); + + put(vpmap, vertices[0], Point_3(0,0,0)); + put(vpmap, vertices[1], Point_3(1,0,0)); + put(vpmap, vertices[2], Point_3(1,1,0)); + put(vpmap, vertices[3], Point_3(0,1,0)); + + edges[0] = add_edge(mesh); + edges[1] = add_edge(mesh); + edges[2] = add_edge(mesh); + edges[3] = add_edge(mesh); + + assert(!CGAL::is_valid_halfedge_graph(mesh)); + for(int i=0; i<4; ++i) + { + set_target(halfedge(edges[i], mesh), vertices[i], mesh); + set_halfedge(vertices[i], halfedge(edges[i], mesh), mesh); + } + + for(int i=0; i<4; ++i) + set_target(opposite(halfedge(edges[i], mesh), mesh), vertices[(i+1)%4], mesh); + for(int i=0; i<4; ++i) + { + set_next(halfedge(edges[(i+1)%4], mesh), halfedge(edges[i], mesh), mesh); + set_next(opposite(halfedge(edges[i], mesh), mesh), + opposite(halfedge(edges[(i+1)%4], mesh), mesh), mesh); + } + + assert(CGAL::is_valid_halfedge_graph(mesh)); + face_descriptor faces[1]; + faces[0] = add_face(mesh); + assert(!CGAL::is_valid_face_graph(mesh)); + + for(int i=0; i<4; ++i) + { + set_face(opposite(halfedge(edges[i], mesh), mesh), faces[0], mesh); + } + set_halfedge(faces[0], opposite(halfedge(edges[0], mesh), mesh), mesh); + assert(CGAL::is_valid_face_graph(mesh)); + assert(CGAL::is_valid_polygon_mesh(mesh)); + + Mesh dummy; + vertices[0] = add_vertex(dummy); + vertices[1] = add_vertex(dummy); + edges[0] = add_edge(dummy); + set_target(halfedge(edges[0], dummy), vertices[0], dummy); + set_halfedge(vertices[0], halfedge(edges[0], dummy), dummy); + set_target(opposite(halfedge(edges[0], dummy), dummy), vertices[1], dummy); + set_halfedge(vertices[1], opposite(halfedge(edges[0], dummy), dummy), dummy); + set_next(halfedge(edges[0], dummy), opposite(halfedge(edges[0], dummy), dummy), dummy); + set_next(opposite(halfedge(edges[0], dummy), dummy), halfedge(edges[0], dummy), dummy); + faces[0] = add_face(dummy); + set_halfedge(faces[0], opposite(halfedge(edges[0], dummy), dummy), dummy); + set_face(halfedge(edges[0], dummy), faces[0], dummy); + set_face(opposite(halfedge(edges[0], dummy), dummy), faces[0], dummy); + assert(CGAL::is_valid_face_graph(dummy)); + assert(!CGAL::is_valid_polygon_mesh(dummy)); + +} + int main() { typedef CGAL::Surface_mesh Mesh; + Mesh mesh; + test_validity(mesh); // triangle quad tetra hexa test("data/triangle.off", true, false, false, false ); test("data/quad.off", false, true, false, false ); @@ -43,43 +120,42 @@ int main() halfedge_descriptor hd; hd = CGAL::make_triangle(a,b,c,m); assert(CGAL::is_isolated_triangle(hd,m)); - assert(CGAL::is_valid(m)); + assert(CGAL::is_valid_polygon_mesh(m)); m.clear(); hd = CGAL::make_quad(a,b,c,d,m); assert(CGAL::is_isolated_quad(hd,m)); - assert(CGAL::is_valid(m)); + assert(CGAL::is_valid_polygon_mesh(m)); assert(CGAL::is_quad_mesh(m)); m.clear(); hd = CGAL::make_tetrahedron(a,b,c,d,m); assert(CGAL::is_tetrahedron(hd,m)); assert(CGAL::is_triangle_mesh(m)); - assert(CGAL::is_valid(m)); + assert(CGAL::is_valid_polygon_mesh(m)); m.clear(); hd = CGAL::make_hexahedron(a,b,c,d,aa,bb,cc,dd,m); assert(CGAL::is_hexahedron(hd,m)); assert(CGAL::is_quad_mesh(m)); - assert(CGAL::is_valid(m)); + assert(CGAL::is_valid_polygon_mesh(m)); m.clear(); CGAL::make_icosahedron(m); assert(num_faces(m) == 20); assert(CGAL::is_triangle_mesh(m)); - assert(CGAL::is_valid(m)); + assert(CGAL::is_valid_polygon_mesh(m)); m.clear(); hd = CGAL::make_pyramid(3, m); assert(num_faces(m) == 6); assert(CGAL::is_triangle_mesh(m)); - assert(CGAL::is_valid(m)); + assert(CGAL::is_valid_polygon_mesh(m)); m.clear(); hd = CGAL::make_regular_prism(4, m); assert(num_faces(m) == 16); assert(CGAL::is_triangle_mesh(m)); - assert(CGAL::is_valid(m)); + assert(CGAL::is_valid_polygon_mesh(m)); m.clear(); CGAL::make_grid(3,3,m); assert(num_faces(m) == 9); assert(CGAL::is_quad_mesh(m)); - assert(CGAL::is_valid(m)); - + assert(CGAL::is_valid_polygon_mesh(m)); std::cerr << "done" << std::endl; return 0; } diff --git a/Bounding_volumes/include/CGAL/Min_annulus_d.h b/Bounding_volumes/include/CGAL/Min_annulus_d.h index f1f349b64fe..2a3f44419df 100644 --- a/Bounding_volumes/include/CGAL/Min_annulus_d.h +++ b/Bounding_volumes/include/CGAL/Min_annulus_d.h @@ -95,7 +95,7 @@ namespace MA_detail { // functor for a fixed column of A template - class A_column : public CGAL::unary_function + class A_column : public CGAL::cpp98::unary_function { public: typedef NT result_type; @@ -133,7 +133,7 @@ namespace MA_detail { // functor for matrix A template - class A_matrix : public CGAL::unary_function + class A_matrix : public CGAL::cpp98::unary_function , boost::counting_iterator > > @@ -167,7 +167,7 @@ namespace MA_detail { // The functor necessary to realize access to b template - class B_vector : public CGAL::unary_function + class B_vector : public CGAL::cpp98::unary_function { public: typedef NT result_type; diff --git a/Bounding_volumes/include/CGAL/Min_quadrilateral_traits_2.h b/Bounding_volumes/include/CGAL/Min_quadrilateral_traits_2.h index ae3e75c2551..ee1dd5b176b 100644 --- a/Bounding_volumes/include/CGAL/Min_quadrilateral_traits_2.h +++ b/Bounding_volumes/include/CGAL/Min_quadrilateral_traits_2.h @@ -129,7 +129,7 @@ public: // new predicates struct Area_less_rectangle_2 - : public CGAL::binary_function< Rectangle_2, Rectangle_2, bool > + : public CGAL::cpp98::binary_function< Rectangle_2, Rectangle_2, bool > { RT area_numerator(const Rectangle_2& r, Cartesian_tag) const @@ -170,7 +170,7 @@ public: } }; struct Area_less_parallelogram_2 - : public CGAL::binary_function< Parallelogram_2, + : public CGAL::cpp98::binary_function< Parallelogram_2, Parallelogram_2, bool > { @@ -215,7 +215,7 @@ public: } }; struct Width_less_strip_2 - : public CGAL::binary_function< Strip_2, Strip_2, bool > + : public CGAL::cpp98::binary_function< Strip_2, Strip_2, bool > { RT width_numerator(const Strip_2& r, Cartesian_tag) const @@ -257,7 +257,7 @@ public: // new constructions struct Construct_vector_from_direction_2 - : public CGAL::unary_function + : public CGAL::cpp98::unary_function { Vector_2 operator()(const Direction_2& d) const { return d.vector(); } }; diff --git a/Bounding_volumes/include/CGAL/Rectangular_p_center_traits_2.h b/Bounding_volumes/include/CGAL/Rectangular_p_center_traits_2.h index 3a136691caa..2762b0e9fa5 100644 --- a/Bounding_volumes/include/CGAL/Rectangular_p_center_traits_2.h +++ b/Bounding_volumes/include/CGAL/Rectangular_p_center_traits_2.h @@ -34,7 +34,7 @@ namespace CGAL { template < class A, class S > -struct Select : public CGAL::binary_function< A, A, A > { +struct Select : public CGAL::cpp98::binary_function< A, A, A > { Select() {} Select(const S& s) : s_(s) {} A operator()(const A& a, const A& b) const @@ -47,7 +47,7 @@ protected: template < class R > struct I_Signed_x_distance_2 -: public CGAL::binary_function< +: public CGAL::cpp98::binary_function< Point_2< R >, Point_2< R >, typename R::FT > { typename R::FT @@ -56,7 +56,7 @@ struct I_Signed_x_distance_2 }; template < class R > struct I_Signed_y_distance_2 -: public CGAL::binary_function< +: public CGAL::cpp98::binary_function< Point_2< R >, Point_2< R >, typename R::FT > { typename R::FT @@ -65,7 +65,7 @@ struct I_Signed_y_distance_2 }; template < class R > struct I_Infinity_distance_2 -: public CGAL::binary_function< +: public CGAL::cpp98::binary_function< Point_2< R >, Point_2< R >, typename R::FT > { typename R::FT @@ -77,7 +77,7 @@ struct I_Infinity_distance_2 template < class R > struct I_Signed_infinity_distance_2 -: public CGAL::binary_function< +: public CGAL::cpp98::binary_function< Point_2< R >, Point_2< R >, typename R::FT > { typename R::FT diff --git a/Bounding_volumes/include/CGAL/min_quadrilateral_2.h b/Bounding_volumes/include/CGAL/min_quadrilateral_2.h index 15a723d8aaf..a31d7158f97 100644 --- a/Bounding_volumes/include/CGAL/min_quadrilateral_2.h +++ b/Bounding_volumes/include/CGAL/min_quadrilateral_2.h @@ -296,7 +296,7 @@ namespace Optimisation { template < class Kernel > class Rdbmop - : public CGAL::binary_function< Direction_2, int, Direction_2 > + : public CGAL::cpp98::binary_function< Direction_2, int, Direction_2 > { typename Kernel::Construct_perpendicular_vector_2 cperpvec; typename Kernel::Construct_vector_from_direction_2 cvec; diff --git a/Bounding_volumes/test/Bounding_volumes/minimum_enclosing_quadrilateral_2_test_traits.cpp b/Bounding_volumes/test/Bounding_volumes/minimum_enclosing_quadrilateral_2_test_traits.cpp index 0aa48fe064b..036920fdb01 100644 --- a/Bounding_volumes/test/Bounding_volumes/minimum_enclosing_quadrilateral_2_test_traits.cpp +++ b/Bounding_volumes/test/Bounding_volumes/minimum_enclosing_quadrilateral_2_test_traits.cpp @@ -40,19 +40,19 @@ struct MyTraits { }; struct Strip_2 { Point_2 pp1, pp2; Direction_2 dd; }; struct Equal_2 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { bool operator()(const Point_2& p, const Point_2& q) const { return p.xc == q.xc && p.yc == q.yc; } }; struct Less_xy_2 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { bool operator()(const Point_2& p, const Point_2& q) const { return p.xc < q.xc || (p.xc == q.xc && p.yc < q.yc); } }; struct Less_yx_2 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { bool operator()(const Point_2& p, const Point_2& q) const { return p.yc < q.yc || (p.yc == q.yc && p.xc < q.xc); } @@ -66,7 +66,7 @@ struct MyTraits { } }; struct Has_on_negative_side_2 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { bool operator()(const Line_2& l, const Point_2& p) const { return @@ -76,14 +76,14 @@ struct MyTraits { } }; struct Compare_angle_with_x_axis_2 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { CGAL::Comparison_result operator()(const Direction_2& d, const Direction_2& e) const { return CGAL::compare_angle_with_x_axisC2(d.xd, d.yd, e.xd, e.yd); } }; struct Area_less_rectangle_2 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { bool operator()(const Rectangle_2& d, const Rectangle_2& e) const { @@ -102,7 +102,7 @@ struct MyTraits { } }; struct Area_less_parallelogram_2 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { bool operator()(const Parallelogram_2& d, const Parallelogram_2& e) const @@ -121,7 +121,7 @@ struct MyTraits { } }; struct Width_less_strip_2 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { bool operator()(const Strip_2& d, const Strip_2& e) const { @@ -134,7 +134,7 @@ struct MyTraits { } }; struct Construct_vector_2 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { Vector_2 operator()(const Point_2& p, const Point_2& q) const { @@ -145,7 +145,7 @@ struct MyTraits { } }; struct Construct_vector_from_direction_2 - : public CGAL::unary_function + : public CGAL::cpp98::unary_function { Vector_2 operator()(const Direction_2& d) const { @@ -156,7 +156,7 @@ struct MyTraits { } }; struct Construct_perpendicular_vector_2 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { Vector_2 operator()(const Vector_2& v, CGAL::Orientation o) const { @@ -172,7 +172,7 @@ struct MyTraits { } }; struct Construct_direction_2 - : public CGAL::unary_function + : public CGAL::cpp98::unary_function { Direction_2 operator()(const Vector_2& v) const { @@ -183,7 +183,7 @@ struct MyTraits { } }; struct Construct_opposite_direction_2 - : public CGAL::unary_function + : public CGAL::cpp98::unary_function { Direction_2 operator()(const Direction_2& d) const { @@ -194,7 +194,7 @@ struct MyTraits { } }; struct Construct_line_2 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { Line_2 operator()(const Point_2& p, const Direction_2& d) const { diff --git a/Box_intersection_d/include/CGAL/Box_intersection_d/Box_traits_d.h b/Box_intersection_d/include/CGAL/Box_intersection_d/Box_traits_d.h index 2bd62c416d2..b354f134288 100644 --- a/Box_intersection_d/include/CGAL/Box_intersection_d/Box_traits_d.h +++ b/Box_intersection_d/include/CGAL/Box_intersection_d/Box_traits_d.h @@ -92,7 +92,7 @@ struct Predicate_traits_d : public BoxTraits { // compare dim a b = islolesslo a b dim class Compare : - public CGAL::binary_function + public CGAL::cpp98::binary_function { int dim; public: @@ -103,7 +103,7 @@ struct Predicate_traits_d : public BoxTraits { }; // loless val dim box = getlo box dim < val - class Lo_less : public CGAL::unary_function { + class Lo_less : public CGAL::cpp98::unary_function { NT value; int dim; public: @@ -113,7 +113,7 @@ struct Predicate_traits_d : public BoxTraits { } }; - class Hi_greater : public CGAL::unary_function { + class Hi_greater : public CGAL::cpp98::unary_function { NT value; int dim; public: @@ -124,7 +124,7 @@ struct Predicate_traits_d : public BoxTraits { }; // spanning lo hi dim box = getlo box dim < lo && gethi box dim > hi - class Spanning : public CGAL::unary_function { + class Spanning : public CGAL::cpp98::unary_function { NT lo, hi; int dim; public: diff --git a/CGAL_Core/include/CGAL/CORE/BigFloat.h b/CGAL_Core/include/CGAL/CORE/BigFloat.h index 4dc7263dfb1..f010ee7696c 100644 --- a/CGAL_Core/include/CGAL/CORE/BigFloat.h +++ b/CGAL_Core/include/CGAL/CORE/BigFloat.h @@ -61,6 +61,8 @@ public: BigFloat(float i) : RCBigFloat(new BigFloatRep(i)) {} /// constructor for int BigFloat(int i) : RCBigFloat(new BigFloatRep(i)) {} + /// constructor for unsigned int + BigFloat(unsigned int i) : RCBigFloat(new BigFloatRep(i)) {} /// constructor for long BigFloat(long l) : RCBigFloat(new BigFloatRep(l)) {} /// constructor for double diff --git a/CGAL_Core/include/CGAL/CORE/BigFloatRep.h b/CGAL_Core/include/CGAL/CORE/BigFloatRep.h index 000ea42deac..74f0de011ae 100644 --- a/CGAL_Core/include/CGAL/CORE/BigFloatRep.h +++ b/CGAL_Core/include/CGAL/CORE/BigFloatRep.h @@ -71,6 +71,7 @@ public: public: // constructors BigFloatRep(int=0); //inline + BigFloatRep(unsigned int); //inline BigFloatRep(short); //inline BigFloatRep(float); //inline BigFloatRep(long); //inline @@ -249,6 +250,9 @@ inline BigFloatRep::BigFloatRep(float n) inline BigFloatRep::BigFloatRep(int n) : m(n), err(0), exp(0) {} +inline BigFloatRep::BigFloatRep(unsigned int n) + : m(n), err(0), exp(0) {} + // Chee (8/8/04) -- introduced constructor from long inline BigFloatRep::BigFloatRep(long n) : m(n), err(0), exp(0) {} diff --git a/CGAL_Core/include/CGAL/CORE/CoreDefs.h b/CGAL_Core/include/CGAL/CORE/CoreDefs.h index 90759e086fa..1d136ab43d1 100644 --- a/CGAL_Core/include/CGAL/CORE/CoreDefs.h +++ b/CGAL_Core/include/CGAL/CORE/CoreDefs.h @@ -41,6 +41,7 @@ #include #include +#include #ifdef CGAL_HEADER_ONLY @@ -54,7 +55,7 @@ #else // CGAL_HEADER_ONLY #define CGAL_GLOBAL_STATE_VAR(TYPE, NAME, VALUE) \ - CGAL_CORE_EXPORT extern TYPE NAME; \ + CGAL_CORE_EXPORT extern TYPE NAME; \ inline TYPE& get_static_##NAME() \ { \ return NAME; \ @@ -340,4 +341,8 @@ inline void setPositionalFormat(std::ostream& o = std::cout) { #include #endif // CGAL_HEADER_ONLY +#include + +#undef CGAL_GLOBAL_STATE_VAR + #endif // _CORE_COREDEFS_H_ diff --git a/CGAL_ImageIO/include/CGAL/ImageIO/bmpendian_impl.h b/CGAL_ImageIO/include/CGAL/ImageIO/bmpendian_impl.h index 581164c0d3f..3a2b7d56b50 100644 --- a/CGAL_ImageIO/include/CGAL/ImageIO/bmpendian_impl.h +++ b/CGAL_ImageIO/include/CGAL/ImageIO/bmpendian_impl.h @@ -56,7 +56,7 @@ int readINT8little(FILE *f, CGAL_INT8 *i) rc = fgetc(f); if (rc == EOF) - return rc; + return EOF; *i = CGAL_INT8(rc & 0xff); return 0; @@ -69,7 +69,7 @@ int readUINT8little(FILE *f, CGAL_UINT8 *i) rc = fgetc(f); if (rc == EOF) - return rc; + return EOF; *i = CGAL_UINT8(rc & 0xff); return 0; @@ -91,7 +91,7 @@ int readINT16little(FILE *f, CGAL_INT16 *i) rc = fgetc(f); if (rc == EOF) - return rc; + return EOF; temp = temp | CGAL_INT16((rc & 0xff) << 8); *i = temp; @@ -108,7 +108,7 @@ int readUINT16little(FILE *f, CGAL_UINT16 *i) rc = fgetc(f); if (rc == EOF) - return rc; + return EOF; temp = CGAL_INT16(temp | ((rc & 0xff) << 8)); *i = temp; @@ -132,7 +132,7 @@ int readINT32little(FILE *f, CGAL_INT32 *i) rc = fgetc(f); if (rc == EOF) - return rc; + return EOF; temp = CGAL_INT32(temp | (((long)rc & 0xff) << 24)); *i = temp; @@ -151,7 +151,7 @@ int readUINT32little(FILE *f, CGAL_UINT32 *i) rc = fgetc(f); if (rc == EOF) - return rc; + return EOF; temp = CGAL_UINT32(temp | (((long)rc & 0xff) << 24)); *i = temp; @@ -185,7 +185,7 @@ int writeINT16little(FILE *f, CGAL_INT16 i) rc = fputc((i & 0xff), f); if (rc == EOF) - return rc; + return EOF; return fputc(((i >> 8) & 0xff), f); } @@ -197,7 +197,7 @@ int writeUINT16little(FILE *f, CGAL_UINT16 i) rc = fputc((i & 0xff), f); if (rc == EOF) - return rc; + return EOF; return fputc(((i >> 8) & 0xff), f); } @@ -209,15 +209,15 @@ int writeINT32little(FILE *f, CGAL_INT32 i) rc = fputc((i & 0xff), f); if (rc == EOF) - return rc; + return EOF; rc = fputc(((i >> 8) & 0xff), f); if (rc == EOF) - return rc; + return EOF; rc = fputc(((i >> 16) & 0xff), f); if (rc == EOF) - return rc; + return EOF; return fputc(((i >> 24) & 0xff), f); } @@ -230,15 +230,15 @@ int writeUINT32little(FILE *f, CGAL_UINT32 i) rc = fputc((i & 0xff), f); if (rc == EOF) - return rc; + return EOF; rc = fputc(((i >> 8) & 0xff), f); if (rc == EOF) - return rc; + return EOF; rc = fputc(((i >> 16) & 0xff), f); if (rc == EOF) - return rc; + return EOF; return fputc(((i >> 24) & 0xff), f); } diff --git a/CGAL_ImageIO/include/CGAL/ImageIO/gif_impl.h b/CGAL_ImageIO/include/CGAL/ImageIO/gif_impl.h index 64e8b484e83..7e9e81c3dfe 100644 --- a/CGAL_ImageIO/include/CGAL/ImageIO/gif_impl.h +++ b/CGAL_ImageIO/include/CGAL/ImageIO/gif_impl.h @@ -699,3 +699,5 @@ static int GifError(const char *st) { return -1; } +#undef CGAL_GLOBAL_STATE_VAR + diff --git a/CGAL_ImageIO/include/CGAL/Image_3.h b/CGAL_ImageIO/include/CGAL/Image_3.h index e13a7e81e08..9b6e9bbd32c 100644 --- a/CGAL_ImageIO/include/CGAL/Image_3.h +++ b/CGAL_ImageIO/include/CGAL/Image_3.h @@ -52,7 +52,7 @@ namespace ImageIO { template struct Indicator_factory { - class Indicator : public CGAL::unary_function + class Indicator : public CGAL::cpp98::unary_function { const T label; public: @@ -503,7 +503,7 @@ Image_3::labellized_trilinear_interpolation static_cast(lc)); if(lc == 1) { - return labels[0]; + return static_cast(labels[0]); } double best_value = 0.; @@ -521,7 +521,7 @@ Image_3::labellized_trilinear_interpolation } } // CGAL_assertion(best_value > 0.5); - return best; + return static_cast(best); } } // end namespace CGAL diff --git a/CGAL_ipelets/demo/CGAL_ipelets/mst.cpp b/CGAL_ipelets/demo/CGAL_ipelets/mst.cpp index 5c78b274eae..d234397890b 100644 --- a/CGAL_ipelets/demo/CGAL_ipelets/mst.cpp +++ b/CGAL_ipelets/demo/CGAL_ipelets/mst.cpp @@ -69,7 +69,7 @@ VertexIndexMap vertex_id_map; typedef boost::associative_property_map VertexIdPropertyMap; VertexIdPropertyMap vertex_index_pmap(vertex_id_map); -void mstIpelet::protected_run(int fn) +void mstIpelet::protected_run(int /*fn*/) { std::list pt_list; diff --git a/CMakeLists.txt b/CMakeLists.txt index 88cfc9acacc..4c884132d3e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,13 +3,33 @@ message( "== CMake setup ==" ) project(CGAL CXX C) # Minimal version of CMake: -cmake_minimum_required(VERSION 2.8.11) +cmake_minimum_required(VERSION 3.1) set( CGAL_BRANCH_BUILD ON CACHE INTERNAL "Create CGAL from a Git branch" FORCE) include(${CMAKE_SOURCE_DIR}/Installation/cmake/modules/CGAL_SCM.cmake) CGAL_detect_git(${CMAKE_SOURCE_DIR}) +function(CGAL_error_if_detect_in_source_build) + # If in a Git repository, forbid in-source builds + get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH) + get_filename_component(bindir "${CMAKE_BINARY_DIR}" REALPATH) + if("${srcdir}" STREQUAL "${bindir}") + message(FATAL_ERROR [=[ +############ +Since CGAL-4.12.1, you can no longer configure an in-source build in a Git +repository. See this StackOverlow question and answers for a way to create +a separate build directory: + https://stackoverflow.com/q/45518317/1728537 +############ +]=]) + endif() +endfunction() + +if ( "${CGAL_SCM_NAME}" STREQUAL "git" ) + CGAL_error_if_detect_in_source_build() +endif() + # add option for duplicate file detection option( CGAL_REPORT_DUPLICATE_FILES "Switch on to start (naive) detection of duplicate source- and headerfiles in packages" OFF) diff --git a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h index 600fe1af0d5..a53b3fe55a8 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h +++ b/Cartesian_kernel/include/CGAL/Cartesian/function_objects.h @@ -3181,6 +3181,7 @@ namespace CartesianKernelFunctors { typedef typename K::Line_3 Line_3; typedef typename K::Triangle_3 Triangle_3; typedef typename K::Segment_3 Segment_3; + typedef typename K::Ray_3 Ray_3; typedef typename K::FT FT; public: typedef Point_3 result_type; @@ -3215,6 +3216,10 @@ namespace CartesianKernelFunctors { Point_3 operator()( const Segment_3& s, const Point_3& p ) const { return CommonKernelFunctors::Construct_projected_point_3()(p,s,K()); } + + Point_3 + operator()( const Ray_3& r, const Point_3& p ) const + { return CommonKernelFunctors::Construct_projected_point_3()(p,r,K()); } }; template diff --git a/Cartesian_kernel/include/CGAL/Cartesian_converter.h b/Cartesian_kernel/include/CGAL/Cartesian_converter.h index d77689adca9..fb25953c85f 100644 --- a/Cartesian_kernel/include/CGAL/Cartesian_converter.h +++ b/Cartesian_kernel/include/CGAL/Cartesian_converter.h @@ -32,6 +32,7 @@ // provided you give a NT converter from A to B. // There's a Homogeneous counterpart. +#include #include #include #include @@ -91,7 +92,7 @@ struct Converting_visitor : boost::static_visitor<> { template < class K1, class K2, // class Converter = NT_converter > - class Converter = typename internal::Default_converter::Type > + class Converter> class Cartesian_converter : public Enum_converter { typedef Enum_converter Base; diff --git a/Circular_kernel_2/test/Circular_kernel_2/test_Circular_kernel.cpp b/Circular_kernel_2/test/Circular_kernel_2/test_Circular_kernel.cpp index 2b62e8bfe47..f40768dfc60 100644 --- a/Circular_kernel_2/test/Circular_kernel_2/test_Circular_kernel.cpp +++ b/Circular_kernel_2/test/Circular_kernel_2/test_Circular_kernel.cpp @@ -24,7 +24,8 @@ // and a STREP (FET Open) Project under Contract No IST-006413 // (ACS -- Algorithms for Complex Shapes) -#define CGAL_NO_DEPRECATION_WARNINGS +#include + #include #include #include diff --git a/Circular_kernel_2/test/Circular_kernel_2/test_Exact_circular_kernel.cpp b/Circular_kernel_2/test/Circular_kernel_2/test_Exact_circular_kernel.cpp index 9bf9357e4bb..0af02760c10 100644 --- a/Circular_kernel_2/test/Circular_kernel_2/test_Exact_circular_kernel.cpp +++ b/Circular_kernel_2/test/Circular_kernel_2/test_Exact_circular_kernel.cpp @@ -24,7 +24,8 @@ // and a STREP (FET Open) Project under Contract No IST-006413 // (ACS -- Algorithms for Complex Shapes) -#define CGAL_NO_DEPRECATION_WARNINGS +#include + #include #include #include diff --git a/Circular_kernel_2/test/Circular_kernel_2/test_Filtered_bbox_circular_kernel.cpp b/Circular_kernel_2/test/Circular_kernel_2/test_Filtered_bbox_circular_kernel.cpp index 3744149cbf6..c3218993be2 100644 --- a/Circular_kernel_2/test/Circular_kernel_2/test_Filtered_bbox_circular_kernel.cpp +++ b/Circular_kernel_2/test/Circular_kernel_2/test_Filtered_bbox_circular_kernel.cpp @@ -24,7 +24,8 @@ // and a STREP (FET Open) Project under Contract No IST-006413 // (ACS -- Algorithms for Complex Shapes) -#define CGAL_NO_DEPRECATION_WARNINGS +#include + #include #include #include diff --git a/Circular_kernel_2/test/Circular_kernel_2/test_Lazy_circular_kernel.cpp b/Circular_kernel_2/test/Circular_kernel_2/test_Lazy_circular_kernel.cpp index 375352c9721..55f9fec7346 100644 --- a/Circular_kernel_2/test/Circular_kernel_2/test_Lazy_circular_kernel.cpp +++ b/Circular_kernel_2/test/Circular_kernel_2/test_Lazy_circular_kernel.cpp @@ -24,7 +24,7 @@ // and a STREP (FET Open) Project under Contract No IST-006413 // (ACS -- Algorithms for Complex Shapes) -#define CGAL_NO_DEPRECATION_WARNINGS 1 +#include #include #include diff --git a/Circular_kernel_3/demo/Circular_kernel_3/CMakeLists.txt b/Circular_kernel_3/demo/Circular_kernel_3/CMakeLists.txt index 1e974c06be3..690ba9517c3 100644 --- a/Circular_kernel_3/demo/Circular_kernel_3/CMakeLists.txt +++ b/Circular_kernel_3/demo/Circular_kernel_3/CMakeLists.txt @@ -11,12 +11,9 @@ include(${CGAL_USE_FILE}) find_package(Qt5 QUIET COMPONENTS Xml Script OpenGL) -find_package(QGLViewer) - -if ( CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND ) +if ( CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND) - include_directories (${QGLVIEWER_INCLUDE_DIR}) include_directories (BEFORE ../../include ./ ) add_executable (Circular_kernel_3 Circular_kernel_3.cpp Viewer.cpp ${CGAL_Qt5_RESOURCE_FILES} ${CGAL_Qt5_MOC_FILES}) @@ -25,7 +22,7 @@ if ( CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND ) target_link_libraries( Circular_kernel_3 PRIVATE CGAL::CGAL CGAL::CGAL_Qt5 - Qt5::OpenGL Qt5::Gui ${QGLVIEWER_LIBRARIES} ) + Qt5::OpenGL Qt5::Gui) include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake) cgal_add_compilation_test(Circular_kernel_3) @@ -35,6 +32,6 @@ if ( CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND ) else() - message(STATUS "NOTICE: This demo requires CGAL, the QGLViewer, and Qt5, and will not be compiled.") + message(STATUS "NOTICE: This demo requires CGAL, and Qt5, and will not be compiled.") endif() diff --git a/Circular_kernel_3/demo/Circular_kernel_3/Viewer.cpp b/Circular_kernel_3/demo/Circular_kernel_3/Viewer.cpp index 1b252a05eb1..6eeff6fd3e0 100644 --- a/Circular_kernel_3/demo/Circular_kernel_3/Viewer.cpp +++ b/Circular_kernel_3/demo/Circular_kernel_3/Viewer.cpp @@ -7,7 +7,7 @@ Viewer::Viewer(QWidget* parent ) - : QGLViewer(CGAL::Qt::createOpenGLContext(),parent) + : CGAL::QGLViewer(parent) { extension_is_found = false; } @@ -316,8 +316,8 @@ void Viewer::compute_elements() - P = rings*M_PI/180.0; - T = t*M_PI/180.0; + P = rings*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[1] = sin(P) * cos(T) ; y[1] = sin(P) * sin(T) ; z[1] = cos(P); @@ -331,8 +331,8 @@ void Viewer::compute_elements() normals.push_back(z[1]); // - P = rings*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = rings*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[2] = sin(P) * cos(T) ; y[2] = sin(P) * sin(T) ; z[2] = cos(P); @@ -351,8 +351,8 @@ void Viewer::compute_elements() for(int t=0; t<360; t+=sectors) { //A - P = p*M_PI/180.0; - T = t*M_PI/180.0; + P = p*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[0] = sin(P) * cos(T) ; y[0] = sin(P) * sin(T) ; z[0] = cos(P); @@ -367,8 +367,8 @@ void Viewer::compute_elements() normals.push_back(z[0]); //B - P = (p+rings)*M_PI/180.0; - T = t*M_PI/180.0; + P = (p+rings)*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[1] = sin(P) * cos(T) ; y[1] = sin(P) * sin(T) ; z[1] = cos(P); @@ -382,8 +382,8 @@ void Viewer::compute_elements() normals.push_back(z[1]); //C - P = p*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = p*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[2] = sin(P) * cos(T) ; y[2] = sin(P) * sin(T) ; z[2] = cos(P); @@ -396,8 +396,8 @@ void Viewer::compute_elements() normals.push_back(y[2]); normals.push_back(z[2]); //D - P = (p+rings)*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = (p+rings)*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[3] = sin(P) * cos(T) ; y[3] = sin(P) * sin(T) ; z[3] = cos(P); @@ -446,8 +446,8 @@ void Viewer::compute_elements() normals.push_back(-1); - P = (180-rings)*M_PI/180.0; - T = t*M_PI/180.0; + P = (180-rings)*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[1] = sin(P) * cos(T) ; y[1] = sin(P) * sin(T) ; z[1] = cos(P); @@ -461,8 +461,8 @@ void Viewer::compute_elements() normals.push_back(z[1]); - P = (180-rings)*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = (180-rings)*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[2] = sin(P) * cos(T) ; y[2] = sin(P) * sin(T) ; z[2] = cos(P); @@ -501,8 +501,8 @@ void Viewer::compute_elements() - P = rings*M_PI/180.0; - T = t*M_PI/180.0; + P = rings*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[1] = sin(P) * cos(T) ; y[1] = sin(P) * sin(T) ; z[1] = cos(P); @@ -516,8 +516,8 @@ void Viewer::compute_elements() normals_inter.push_back(z[1]); // - P = rings*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = rings*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[2] = sin(P) * cos(T) ; y[2] = sin(P) * sin(T) ; z[2] = cos(P); @@ -536,8 +536,8 @@ void Viewer::compute_elements() for(int t=0; t<360; t+=sectors) { //A - P = p*M_PI/180.0; - T = t*M_PI/180.0; + P = p*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[0] = sin(P) * cos(T) ; y[0] = sin(P) * sin(T) ; z[0] = cos(P); @@ -552,8 +552,8 @@ void Viewer::compute_elements() normals_inter.push_back(z[0]); //B - P = (p+rings)*M_PI/180.0; - T = t*M_PI/180.0; + P = (p+rings)*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[1] = sin(P) * cos(T) ; y[1] = sin(P) * sin(T) ; z[1] = cos(P); @@ -567,8 +567,8 @@ void Viewer::compute_elements() normals_inter.push_back(z[1]); //C - P = p*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = p*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[2] = sin(P) * cos(T) ; y[2] = sin(P) * sin(T) ; z[2] = cos(P); @@ -581,8 +581,8 @@ void Viewer::compute_elements() normals_inter.push_back(y[2]); normals_inter.push_back(z[2]); //D - P = (p+rings)*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = (p+rings)*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[3] = sin(P) * cos(T) ; y[3] = sin(P) * sin(T) ; z[3] = cos(P); @@ -631,8 +631,8 @@ void Viewer::compute_elements() normals_inter.push_back(-1); - P = (180-rings)*M_PI/180.0; - T = t*M_PI/180.0; + P = (180-rings)*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[1] = sin(P) * cos(T) ; y[1] = sin(P) * sin(T) ; z[1] = cos(P); @@ -646,8 +646,8 @@ void Viewer::compute_elements() normals_inter.push_back(z[1]); - P = (180-rings)*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = (180-rings)*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[2] = sin(P) * cos(T) ; y[2] = sin(P) * sin(T) ; z[2] = cos(P); @@ -722,7 +722,7 @@ void Viewer::compute_elements() } } -void Viewer::attrib_buffers(QGLViewer* viewer) +void Viewer::attrib_buffers(CGAL::QGLViewer* viewer) { QMatrix4x4 mvpMatrix; QMatrix4x4 mvMatrix; diff --git a/Circular_kernel_3/demo/Circular_kernel_3/Viewer.h b/Circular_kernel_3/demo/Circular_kernel_3/Viewer.h index 661949b46e3..ea178e756a0 100644 --- a/Circular_kernel_3/demo/Circular_kernel_3/Viewer.h +++ b/Circular_kernel_3/demo/Circular_kernel_3/Viewer.h @@ -1,5 +1,5 @@ #include -#include +#include #include #include @@ -9,7 +9,7 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel EPIC; -class Viewer : public QGLViewer, QOpenGLFunctions_2_1 +class Viewer : public CGAL::QGLViewer { public: Viewer(QWidget* parent = 0); @@ -52,7 +52,7 @@ private: void initialize_buffers(); void compute_elements(); - void attrib_buffers(QGLViewer*); + void attrib_buffers(CGAL::QGLViewer*); void compile_shaders(); }; diff --git a/Classification/include/CGAL/Classification/Planimetric_grid.h b/Classification/include/CGAL/Classification/Planimetric_grid.h index f295761f0f2..886cbc83105 100644 --- a/Classification/include/CGAL/Classification/Planimetric_grid.h +++ b/Classification/include/CGAL/Classification/Planimetric_grid.h @@ -114,7 +114,7 @@ public: for (std::size_t x = xmin; x < m_xmax; ++ x) { for (std::size_t y = m_ymin; y < m_ymax; ++ y) - if (m_lowest_scale->has_points(x,y)) + if (lowest_scale_has_points(x,y)) { m_pos_x = x; m_pos_y = y; @@ -154,7 +154,7 @@ public: } } - while (!(m_lowest_scale->has_points(m_pos_x, m_pos_y))); + while (!(lowest_scale_has_points(m_pos_x, m_pos_y))); } } @@ -180,6 +180,13 @@ public: std::size_t m_pos_x; std::size_t m_pos_y; + bool lowest_scale_has_points (std::size_t x, std::size_t y) const + { + if (x >= m_lowest_scale->width() || y >= m_lowest_scale->height()) + return false; + return m_lowest_scale->has_points (x, y); + } + }; #endif @@ -213,7 +220,6 @@ public: m_y.push_back ((std::size_t)((p.y() - bbox.ymin()) / grid_resolution)); m_grid(m_x.back(), m_y.back()).push_back (i); } -// std::cerr << "Grid size = " << width << " " << height << std::endl; } /// \cond SKIP_IN_MANUAL @@ -229,12 +235,32 @@ public: for (std::size_t x = 0; x < m_width; ++ x) for (std::size_t y = 0; y < m_height; ++ y) { - m_has_points.push_back ((m_lower_scale->has_points(x*2, y*2) - || m_lower_scale->has_points(x*2, y*2 + 1) - || m_lower_scale->has_points(x*2 + 1, y*2 + 1) - || m_lower_scale->has_points(x*2 + 1, y*2))); + bool has_points = false; + + for (std::size_t i = 0; i <= 1; ++ i) + { + std::size_t xi = x*2 + i; + if (xi >= m_lower_scale->width()) + continue; + + for (std::size_t j = 0; j <= 1; ++ j) + { + std::size_t yi = y*2 + j; + if (yi >= m_lower_scale->height()) + continue; + + if (m_lower_scale->has_points(xi,yi)) + { + has_points = true; + break; + } + } + if (has_points) + break; + } + + m_has_points.push_back (has_points); } -// std::cerr << "Grid size = " << width() << " " << height() << std::endl; } /// \endcond @@ -267,8 +293,9 @@ public: { if (m_current_scale == 0) return this; - else - return m_lower_scale->lowest_scale(); + + // else + return m_lower_scale->lowest_scale(); } /// \endcond @@ -278,6 +305,8 @@ public: */ iterator indices_begin(std::size_t x, std::size_t y) const { + CGAL_assertion (x < m_width && y < m_height); + return iterator (lowest_scale(), m_current_scale, x, y); } @@ -287,6 +316,8 @@ public: */ iterator indices_end(std::size_t x, std::size_t y) const { + CGAL_assertion (x < m_width && y < m_height); + return iterator (lowest_scale(), m_current_scale, x, y, true); } @@ -295,14 +326,13 @@ public: */ bool has_points(std::size_t x, std::size_t y) const { + CGAL_assertion (x < m_width && y < m_height); + if (m_current_scale == 0) - { - if (x >= m_grid.width() || y >= m_grid.height()) - return false; return (!(m_grid(x,y).empty())); - } - else - return m_has_points[x * m_height + y]; + + // else + return m_has_points[x * m_height + y]; } /*! @@ -312,8 +342,9 @@ public: { if (m_lower_scale == NULL) return m_x[index]; - else - return m_lower_scale->x(index) / 2; + + // else + return m_lower_scale->x(index) / 2; } /*! \brief Returns the `y` grid coordinate of the point at position `index`. @@ -322,8 +353,9 @@ public: { if (m_lower_scale == NULL) return m_y[index]; - else - return m_lower_scale->y(index) / 2; + + // else + return m_lower_scale->y(index) / 2; } }; diff --git a/Classification/include/CGAL/Classification/Point_set_feature_generator.h b/Classification/include/CGAL/Classification/Point_set_feature_generator.h index 04c476d6548..b74ef1d16f6 100644 --- a/Classification/include/CGAL/Classification/Point_set_feature_generator.h +++ b/Classification/include/CGAL/Classification/Point_set_feature_generator.h @@ -496,7 +496,7 @@ private: launch_feature_computation (new Feature_adder_verticality (this, normal_map, 0)); } - void generate_normal_based_features(const CGAL::Default_property_map&) + void generate_normal_based_features(const CGAL::Constant_property_map&) { generate_multiscale_feature_variant_0 (); } @@ -544,7 +544,7 @@ private: 2, 25.f * float(i), 12.5f)); } - void generate_color_based_features(const CGAL::Default_property_map&) + void generate_color_based_features(const CGAL::Constant_property_map&) { } @@ -581,7 +581,7 @@ private: launch_feature_computation (new Feature_adder_echo (this, echo_map, i)); } - void generate_echo_based_features(const CGAL::Default_property_map&) + void generate_echo_based_features(const CGAL::Constant_property_map&) { } @@ -615,10 +615,10 @@ private: } template - Default_property_map + Constant_property_map get_parameter (const Default&) { - return Default_property_map(); + return Constant_property_map(); } template diff --git a/Combinatorial_map/examples/Combinatorial_map/map_3_foreach.cpp b/Combinatorial_map/examples/Combinatorial_map/map_3_foreach.cpp index 5d9cbecd8eb..3d99c3d8eac 100644 --- a/Combinatorial_map/examples/Combinatorial_map/map_3_foreach.cpp +++ b/Combinatorial_map/examples/Combinatorial_map/map_3_foreach.cpp @@ -8,7 +8,7 @@ typedef CMap_3::Dart_handle Dart_handle; // Functor used to display all the vertices of a given volume template -struct Display_vertices_of_cell : public CGAL::unary_function +struct Display_vertices_of_cell : public CGAL::cpp98::unary_function { Display_vertices_of_cell(const CMap& acmap) : cmap(acmap), @@ -40,7 +40,7 @@ private: // Functor used to remove a face template -struct Remove_face : public CGAL::unary_function +struct Remove_face : public CGAL::cpp98::unary_function { Remove_face(CMap& acmap) : cmap(acmap) {} @@ -60,7 +60,7 @@ private: // Functor allowing to transform a variable into its address. template -struct Take_adress : public CGAL::unary_function +struct Take_adress : public CGAL::cpp98::unary_function { T* operator() (T& t) const { return &t; } diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map.h b/Combinatorial_map/include/CGAL/Combinatorial_map.h index d6da5650c85..4c2bb810685 100644 --- a/Combinatorial_map/include/CGAL/Combinatorial_map.h +++ b/Combinatorial_map/include/CGAL/Combinatorial_map.h @@ -1250,7 +1250,7 @@ namespace CGAL { /** Test if the map is valid. * @return true iff the map is valid. */ - bool is_valid() const + bool is_valid(bool show_errors=true) const { bool valid = true; unsigned int i = 0, j = 0; @@ -1276,9 +1276,11 @@ namespace CGAL { if ((!is_free(it, 0) && beta(it, 0, 1)!=it) || (!is_free(it, 1) && beta(it, 1, 0)!=it )) { - std::cerr << "Map not valid: beta(0) " - "is not the inverse of beta(1) for dart " - < + for ( typename CMap::template Dart_of_cell_basic_range::iterator it(amap, adart, amark); it.cont(); ++it, ++nb ) { if ( a!=amap.template attribute(it) ) diff --git a/Combinatorial_map/test/Combinatorial_map/Combinatorial_map_deprecated_test.cpp b/Combinatorial_map/test/Combinatorial_map/Combinatorial_map_deprecated_test.cpp index 8f8a166626b..ddb22aff1fa 100644 --- a/Combinatorial_map/test/Combinatorial_map/Combinatorial_map_deprecated_test.cpp +++ b/Combinatorial_map/test/Combinatorial_map/Combinatorial_map_deprecated_test.cpp @@ -1,8 +1,7 @@ #include -#ifndef CGAL_NO_DEPRECATED_CODE +#include -#define CGAL_NO_DEPRECATION_WARNINGS 1 #define CGAL_CMAP_DART_DEPRECATED 1 #include @@ -88,12 +87,3 @@ int main() std::cout<<" Success."< -class Less_by_direction_2 : public CGAL::binary_function { - +class Less_by_direction_2 + : public CGAL::cpp98::binary_function +{ public: // typedef for C++11 - doesn't hurt to also have for C++98 typedef typename Graph_::vertex_descriptor first_argument_type; diff --git a/Convex_hull_3/test/Convex_hull_3/test_halfspace_intersections.cpp b/Convex_hull_3/test/Convex_hull_3/test_halfspace_intersections.cpp index 7e0e00e9345..385236066d9 100644 --- a/Convex_hull_3/test/Convex_hull_3/test_halfspace_intersections.cpp +++ b/Convex_hull_3/test/Convex_hull_3/test_halfspace_intersections.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include diff --git a/Convex_hull_d/test/Convex_hull_d/chull_d-test.cpp b/Convex_hull_d/test/Convex_hull_d/chull_d-test.cpp index deb92fa0319..16efa8310b1 100644 --- a/Convex_hull_d/test/Convex_hull_d/chull_d-test.cpp +++ b/Convex_hull_d/test/Convex_hull_d/chull_d-test.cpp @@ -1,4 +1,4 @@ -#define CGAL_NO_DEPRECATION_WARNINGS +#include #include #include diff --git a/Convex_hull_d/test/Convex_hull_d/delaunay_d-test.cpp b/Convex_hull_d/test/Convex_hull_d/delaunay_d-test.cpp index 8b4abb1aee5..72bfb288c6c 100644 --- a/Convex_hull_d/test/Convex_hull_d/delaunay_d-test.cpp +++ b/Convex_hull_d/test/Convex_hull_d/delaunay_d-test.cpp @@ -1,4 +1,4 @@ -#define CGAL_NO_DEPRECATION_WARNINGS +#include #include #include diff --git a/Documentation/doc/Documentation/General.txt b/Documentation/doc/Documentation/General.txt index 1afb38e746c..0941991e41c 100644 --- a/Documentation/doc/Documentation/General.txt +++ b/Documentation/doc/Documentation/General.txt @@ -15,6 +15,11 @@ class DefaultConstructible {}; /// See http://en.cppreference.com/w/cpp/concept/CopyConstructible class CopyConstructible {}; +/// \cgalConcept +/// Concept from the \cpp standard. +/// See http://en.cppreference.com/w/cpp/concept/Callable +class Callable {}; + /// \cgalConcept /// Concept from the \cpp standard. /// See http://en.cppreference.com/w/cpp/concept/EqualityComparable diff --git a/Documentation/doc/Documentation/Installation.txt b/Documentation/doc/Documentation/Installation.txt index dfb970b63f0..9516d1779c8 100644 --- a/Documentation/doc/Documentation/Installation.txt +++ b/Documentation/doc/Documentation/Installation.txt @@ -18,13 +18,13 @@ make # build the \cgal libraries Compiling an example or a demo shipped with \cgal is similarly simple:
-cd examples/Straight_skeleton_2 # go to an example directory
+cd examples/Triangulation_2 # go to an example directory
 cmake -DCGAL_DIR=$HOME/CGAL-\cgalReleaseNumber . # configure the examples
 make # build the examples 
 
-cd demo/Straight_skeleton_2 # go to a demo directory
+cd demo/Triangulation_2 # go to a demo directory
 cmake -DCGAL_DIR=$HOME/CGAL-\cgalReleaseNumber . # configure the demos
 make # build the demos 
 
@@ -41,11 +41,6 @@ make where the second line creates a `CMakeLists.txt` file (check its options in Section \ref seccreate_cgal_CMakeLists for various details). -Note that, until CGAL 4.6, \ref seccreate_cgal_CMakeLists only recognized -source files ending in `.cpp` or `.C`; if the above fails on the `cmake` command -or produces an empty `Makefile`, check whether your source files go by such a name. -Recent versions find all source files ending in -`.cc`, `.cp`, `.cxx`, `.cpp`, `.CPP`, `.c++`, or `.C`. In a less ideal world, you probably have to install CMake, a makefile generator, and third party libraries. That is what this manual is about. @@ -105,7 +100,7 @@ It is a self extracting executable that installs the \cgal source, and that allo to select and download some precompiled third party libraries. However, you will need to compile the library using your favorite compiler. -A tutorial is provided on how to proceed with Microsoft Visual Studio 2010. +A tutorial is provided on how to proceed with Microsoft Visual Studio. @@ -157,17 +152,18 @@ installation manual. The \cgal manual must be downloaded separately from \section seccompilers Supported Compilers In order to build the \cgal libraries, you need a \cpp compiler. -\cgal \cgalReleaseNumber is supported for the following compilers/operating systems: +\cgal \cgalReleaseNumber is supported, that is continuously tested, for the following compilers/operating systems: | Compiler | Operating System | | :------- | :--------------- | |\sc{Gnu} `g++` 4.1 or later\cgalFootnote{`http://gcc.gnu.org/`} | Linux / MacOS X | -| | \sc{MS} Windows 95/98/2000/XP/NT4 | -| \sc{Intel} `C++` 15.0\cgalFootnote{`http://software.intel.com/en-us/intel-compilers/`} | Linux | -|\sc{MS} Visual `C++` 10.0, 11.0, 12.0, 14.0 (\sc{Visual Studio} 2010, 2012, 2013, and 2015)\cgalFootnote{`http://msdn.microsoft.com/en-us/vstudio/`} | \sc{MS} Windows 95/98/2000/XP/NT4/Vista/7/8 | -| `Clang` \cgalFootnote{`http://clang.llvm.org/`} compiler version 3.5 and 3.6.2 | Linux / MacOS X | -| Apple `Clang` compiler version 6.0 and 4.2 | MacOS X | +| | \sc{MS} Windows | +|\sc{MS} Visual `C++` 12.0, 14.0, 15.0 (\sc{Visual Studio} 2013, 2015, and 2017)\cgalFootnote{`http://msdn.microsoft.com/en-us/vstudio/`} | \sc{MS} Windows | +| `Clang` \cgalFootnote{`http://clang.llvm.org/`} compiler version 6.0.0 | Linux | +| Apple `Clang` compiler version 7.0.2 | MacOS X | + +It may work for older versions of the above listed compilers. \section secconfigwithcmake Configuring CGAL with CMake @@ -247,11 +243,11 @@ generators are added with each release. Since the choice of the generator determines the type of build files to generate, in some cases you choose a particular generator as a mean to choose a specific compiler (because they use different build files). For example, the following generates solution files for -use in Visual \cpp 11.0 on a 64bit machine: +use in Visual \cpp 15.0 on a 64bit machine:
 cd CGAL-\cgalReleaseNumber
-cmake -G"Visual Studio 11 Win64" . 
+cmake -G"Visual Studio 15 2017 Win64" . 
 
In other cases, however, the generator doesn't directly identify a @@ -381,8 +377,8 @@ libCGAL_Core, libCGAL_ImageIO, and libCGAL_Qt5). \cgal heavily uses the \stl, and in particular adopted many of its design ideas. You can find online documentation for the \stl at various web sites, for instance, -`http://www.sgi.com/tech/stl/`, `http://www.cplusplus.com/reference/`, -or `http://msdn.microsoft.com/en-us/library/1fe2x6kt(VS.100).aspx`. +`http://www.cplusplus.com/reference/`, +or `https://msdn.microsoft.com/en-us/library/1fe2x6kt(v=vs.140).aspx`. The \stl comes with the compiler, so there is nothing to install. @@ -555,14 +551,6 @@ and the \ref PkgRidges_3 packages. The \sc{Eigen} web site is `http://eigen.tuxfamily.org`. -\subsection thirdpartylibQGLViewer libQGLViewer - -libQGLViewer is a 3D widget based on \sc{Qt} 4's `QGLWidget`. In case of \sc{Qt}5 used, libQGLViewer needs to be recompiled with the proper \sc{Qt}5 version. - -In \cgal some 3D demos are based on libQGLViewer. - -It can be downloaded from `http://www.libqglviewer.com/`. - \subsection thirdpartyESBTL ESBTL The \sc{Esbtl} (Easy Structural Biology Template Library) is a library that allows @@ -677,9 +665,6 @@ make examples # build all demos at once make demos -# build only the Straight Skeleton demo -make Straight_skeleton_2_demo - \cgalAdvancedBegin @@ -761,7 +746,7 @@ Ideally, configuring and compiling a demo/example/program amounts to
 
-cd CGAL-\cgalReleaseNumber/examples/Straight_skeleton_2
+cd CGAL-\cgalReleaseNumber/examples/Triangulation_2
 cmake -DCGAL_DIR=$HOME/CGAL-\cgalReleaseNumber .
 make
 
@@ -897,7 +882,7 @@ controlling variable right up front:
 
 cd CGAL-\cgalReleaseNumber
 cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS=-g .
-cd CGAL-\cgalReleaseNumber/examples/Straight_skeleton_2
+cd CGAL-\cgalReleaseNumber/examples/Triangulation_2
 cmake -DCGAL_DIR=CGAL-\cgalReleaseNumber -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS=-O2 -DCGAL_DONT_OVERRIDE_CMAKE_FLAGS=TRUE . 
 
\cgalAdvancedEnd @@ -1176,22 +1161,6 @@ Only the directory containing the header files of \sc{Eigen} 3.1 (or grea | `EIGEN3_INCLUDE_DIR` | Directory containing the file `signature_of_eigen3_matrix_library` | CMake | | `EIGEN3_INC_DIR` | Idem | Environment | -\subsection installation_qgl QGLViewer Library - -Some demos require the GLViewer library. - -In most cases, if QGLViewer is not automatically found, setting the `QGLVIEWERROOT` -environment variable is sufficient. If it is not, you can specify the directory containing -the header files and the full pathnames of the release and debug libraries - -| Variable | Description | Type | -| :- | :- | :- | -| `QGLVIEWERROOT` | Root directory of the QGLViewer library | Environment | -| `QGLVIEWER_INCLUDE_DIR` | Directory containing the `QGLViewer/qglviewer.h` file | CMake | -| `QGLVIEWER_LIBRARY_RELEASE` | Full pathname to a release build of the QGLViewer library | CMake | -| `QGLVIEWER_LIBRARY_DEBUG` | Full pathname to a debug build of the QGLViewer library | CMake | - - \subsection installation_esbtl ESBTL Library One skin surface example requires the \sc{Esbtl} library in order to read \sc{Pdb} files. diff --git a/Documentation/doc/resources/1.8.13/BaseDoxyfile.in b/Documentation/doc/resources/1.8.13/BaseDoxyfile.in index a6bc2bbb17e..49b2e2c11b3 100644 --- a/Documentation/doc/resources/1.8.13/BaseDoxyfile.in +++ b/Documentation/doc/resources/1.8.13/BaseDoxyfile.in @@ -1571,7 +1571,7 @@ MATHJAX_FORMAT = HTML-CSS # The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2. # This tag requires that the tag USE_MATHJAX is set to YES. -${CGAL_DOC_MATHJAX_LOCATION_FULL_OPTION_LINE} +MATHJAX_RELPATH = ${CGAL_DOC_MATHJAX_LOCATION} # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example diff --git a/Documentation/doc/scripts/testsuite.py b/Documentation/doc/scripts/testsuite.py index ab8bffec92a..3bc49ffdc22 100755 --- a/Documentation/doc/scripts/testsuite.py +++ b/Documentation/doc/scripts/testsuite.py @@ -78,7 +78,8 @@ body {color: black; background-color: #C0C0D0; font-family: sans-serif;}

Doxygen Manual Results

''' - page_footer=''' + page_footer='''
+ @@ -101,7 +102,7 @@ body {color: black; background-color: #C0C0D0; font-family: sans-serif;} suffix = '' if args.doxygen_version2: suffix = args.doxygen_version2 - link2="\n
Documentation built with our fork of Doxygen {_suffix}\n".format(_suffix=suffix) + link2="\n
Documentation built with our fork of Doxygen {_suffix} (used for the official CGAL documentation)\n".format(_suffix=suffix) suffix = '' if args.master_describe: suffix=args.master_describe diff --git a/Filtered_kernel/include/CGAL/Epic_converter.h b/Filtered_kernel/include/CGAL/Epic_converter.h index 6dc96801973..bd4650c4c2a 100644 --- a/Filtered_kernel/include/CGAL/Epic_converter.h +++ b/Filtered_kernel/include/CGAL/Epic_converter.h @@ -23,7 +23,7 @@ #define CGAL_EPIC_CONVERTER_H -#include +#include #include namespace CGAL { @@ -54,6 +54,8 @@ class Epic_converter { typedef typename Exact_predicates_inexact_constructions_kernel::Sphere_3 Sphere_3; typedef typename Exact_predicates_inexact_constructions_kernel::Circle_3 Circle_3; typedef typename Exact_predicates_inexact_constructions_kernel::Iso_cuboid_3 Iso_cuboid_3; + + typedef typename IK::FT IK_FT; public: @@ -61,6 +63,7 @@ public: std::pair operator()(const typename IK::FT n) const { double d; + internal::init_double(d, (IK_FT*)(0)); if(fit_in_double(n,d)){ return std::make_pair(d,true); } @@ -80,6 +83,7 @@ public: std::pair operator()(const typename IK::Point_2& p) const { double x, y; + internal::init_double(x, y, (IK_FT*)(0)); if(fit_in_double(p.x(),x) && fit_in_double(p.y(),y)){ return std::make_pair(Point_2(x,y),true); } @@ -89,6 +93,7 @@ public: std::pair operator()(const typename IK::Vector_2& v) const { double x, y; + internal::init_double(x, y, (IK_FT*)(0)); if(fit_in_double(v.x(),x) && fit_in_double(v.y(),y)){ return std::make_pair(Vector_2(x,y),true); } @@ -98,6 +103,7 @@ public: std::pair operator()(const typename IK::Direction_2& d) const { double x, y; + internal::init_double(x, y, (IK_FT*)(0)); if(fit_in_double(d.dx(),x) && fit_in_double(d.dy(),y)){ return std::make_pair(Direction_2(x,y),true); } @@ -266,6 +272,7 @@ public: std::pair operator()(const typename IK::Point_3& p) const { double x, y, z; + internal::init_double(x, y, z, (IK_FT*)(0)); if(fit_in_double(p.x(),x) && fit_in_double(p.y(),y) && fit_in_double(p.z(),z)){ return std::make_pair(Point_3(x,y,z),true); } @@ -275,6 +282,7 @@ public: std::pair operator()(const typename IK::Vector_3& v) const { double x, y, z; + internal::init_double(x, y, z, (IK_FT*)(0)); if(fit_in_double(v.x(),x) && fit_in_double(v.y(),y) && fit_in_double(v.z(),z)){ return std::make_pair(Vector_3(x,y,z),true); } @@ -284,6 +292,7 @@ public: std::pair operator()(const typename IK::Direction_3& d) const { double x, y, z; + internal::init_double(x, y, z, (IK_FT*)(0)); if(fit_in_double(d.dx(),x) && fit_in_double(d.dy(),y) && fit_in_double(d.dz(),z)){ return std::make_pair(Direction_3(x,y,z),true); } diff --git a/Filtered_kernel/include/CGAL/Lazy.h b/Filtered_kernel/include/CGAL/Lazy.h index 1cfb6838fe5..c54296e8767 100644 --- a/Filtered_kernel/include/CGAL/Lazy.h +++ b/Filtered_kernel/include/CGAL/Lazy.h @@ -55,6 +55,12 @@ namespace CGAL { +template +class Lazy_kernel_base; + template class Lazy; template @@ -425,13 +431,19 @@ class Lazy_rep_##n :public Lazy_rep< AT, \ E2A >, \ private EC \ { \ + \ + template \ + friend class Lazy_kernel_base; \ BOOST_PP_REPEAT(n, CGAL_MLIST, _) \ const EC& ec() const { return *this; } \ public: \ void update_exact() const { \ - this->et = new ET(ec()( BOOST_PP_ENUM(n, CGAL_LEXACT, _) ) ); \ - this->at = E2A()(*(this->et)); \ - BOOST_PP_REPEAT(n, CGAL_PRUNE_TREE, _) \ + this->et = new ET(ec()( BOOST_PP_ENUM(n, CGAL_LEXACT, _) ) ); \ + this->at = E2A()(*(this->et)); \ + BOOST_PP_REPEAT(n, CGAL_PRUNE_TREE, _) \ } \ Lazy_rep_##n(const AC& ac, const EC&, BOOST_PP_ENUM(n, CGAL_LARGS, _)) \ : Lazy_rep(ac( BOOST_PP_ENUM(n, CGAL_LN, CGAL::approx) )), BOOST_PP_ENUM(n, CGAL_LINIT, _) \ @@ -714,6 +726,17 @@ public: template class Lazy : public Handle { + template + friend struct Lazy_kernel; + + template + friend class Lazy_kernel_base; + public : typedef Lazy Self; @@ -784,7 +807,7 @@ public : ptr()->print_dag(os, level); } -private: + private: // We have a static variable for optimizing the default constructor, // which is in particular heavily used for pruning DAGs. diff --git a/Filtered_kernel/include/CGAL/Lazy_kernel.h b/Filtered_kernel/include/CGAL/Lazy_kernel.h index 521215d6576..2639a9f7027 100644 --- a/Filtered_kernel/include/CGAL/Lazy_kernel.h +++ b/Filtered_kernel/include/CGAL/Lazy_kernel.h @@ -304,6 +304,7 @@ public: typedef EK_ Exact_kernel; typedef E2A_ E2A; + typedef Lazy_kernel_generic_base BaseClass; template < typename Kernel2 > struct Base { typedef Lazy_kernel_base Type; }; @@ -320,6 +321,213 @@ public: // typedef void Compute_z_3; // to detect where .z() is called // typedef void Construct_point_3; // to detect where the ctor is called + struct Compute_weight_2 : public BaseClass::Compute_weight_2 + { + typedef typename Kernel_::FT FT; + typedef typename Kernel_::Point_2 Point_2; + typedef typename Kernel_::Weighted_point_2 Weighted_point_2; + + FT operator()(const Weighted_point_2& p) const + { + + typedef Lazy_rep_3 LR; + + + LR * lr = dynamic_cast(p.ptr()); + if(lr && (! lr->et)){ + return lr->l2; + } + return BaseClass().compute_weight_2_object()(p); + } + + }; + + + struct Compute_weight_3 : public BaseClass::Compute_weight_3 + { + typedef typename Kernel_::FT FT; + typedef typename Kernel_::Point_3 Point_3; + typedef typename Kernel_::Weighted_point_3 Weighted_point_3; + + FT operator()(const Weighted_point_3& p) const + { + + typedef Lazy_rep_3 LR; + + + LR * lr = dynamic_cast(p.ptr()); + if(lr && (! lr->et)){ + return lr->l2; + } + return BaseClass().compute_weight_3_object()(p); + } + + }; + + + struct Construct_point_2 : public BaseClass::Construct_point_2 + { + typedef typename Kernel_::FT FT; + typedef typename Kernel_::Point_2 Point_2; + typedef typename Kernel_::Weighted_point_2 Weighted_point_2; + +#ifndef CGAL_CFG_MATCHING_BUG_6 + using BaseClass::Construct_point_2::operator(); +#else // CGAL_CFG_MATCHING_BUG_6 + + + template + Point_2 operator()(const T& ...t) const + { + return BaseClass().construct_point_2_object()(t...); + } + +#endif // CGAL_CFG_MATCHING_BUG_6 + + const Point_2& operator()(const Point_2& p) const + { + return p; + } + + + Point_2 operator()(const Weighted_point_2& p) const + { + typedef Lazy_rep_3 LR; + + typedef Lazy_rep_3 LRint; + + LR * lr = dynamic_cast(p.ptr()); + if(lr && (! lr->et)){ + return lr->l1; + } else { + LRint* lrint = dynamic_cast(p.ptr()); + if(lrint && (! lrint->et)){ + return lrint->l1; + } + } + + return BaseClass().construct_point_2_object()(p); + } + + }; + + + + struct Construct_point_3 : public BaseClass::Construct_point_3 + { + typedef typename Kernel_::FT FT; + typedef typename Kernel_::Point_3 Point_3; + typedef typename Kernel_::Weighted_point_3 Weighted_point_3; + +#ifndef CGAL_CFG_MATCHING_BUG_6 + using BaseClass::Construct_point_3::operator(); +#else // CGAL_CFG_MATCHING_BUG_6 + + template + Point_3 operator()(const T& ...t) const + { + return BaseClass().construct_point_3_object()(t...); + } + +#endif // CGAL_CFG_MATCHING_BUG_6 + + const Point_3& operator()(const Point_3& p) const + { + return p; + } + + Point_3 operator()(const Weighted_point_3& p) const + { + typedef Lazy_rep_3 LR; + + typedef Lazy_rep_3 LRint; + + + LR * lr = dynamic_cast(p.ptr()); + if(lr && (! lr->et)){ + return lr->l1; + }else{ + LRint* lrint = dynamic_cast(p.ptr()); + if(lrint && (! lrint->et)){ + return lrint->l1; + } + } + return BaseClass().construct_point_3_object()(p); + } + + }; + + + Construct_point_2 construct_point_2_object() const + { + return Construct_point_2(); + } + + Construct_point_3 construct_point_3_object() const + { + return Construct_point_3(); + } + + + Compute_weight_2 compute_weight_2_object() const + { + return Compute_weight_2(); + } + + Compute_weight_3 compute_weight_3_object() const + { + return Compute_weight_3(); + } + + Assign_2 assign_2_object() const { return Assign_2(); } diff --git a/Filtered_kernel/include/CGAL/internal/Static_filters/tools.h b/Filtered_kernel/include/CGAL/internal/Static_filters/tools.h index 44a69734f5b..59d60fe902e 100644 --- a/Filtered_kernel/include/CGAL/internal/Static_filters/tools.h +++ b/Filtered_kernel/include/CGAL/internal/Static_filters/tools.h @@ -31,6 +31,9 @@ namespace CGAL { template < typename ET > class Lazy_exact_nt; +template +class Interval_nt; + namespace internal { // Utility function to check a posteriori that a subtraction was performed @@ -152,6 +155,66 @@ template < typename ET > inline void init_double(double& d0, double& d1, double& d2, double& d3, double& d4, double& d5, double& d6, double& d7, double&d8, double& d9, double& d10, double& d11, double& d12, double& d13, double& d14, Lazy_exact_nt* ) {d0 = d1 = d2 = d3 = d4 = d5 = d6 = d7 = d8 = d9 = d10 = d11 = d12 = d13 = d14 = 0;} +template < bool P > +inline void init_double(double& d0, Interval_nt

* ) +{d0 = 0;} + +template < bool P > +inline void init_double(double& d0, double& d1, Interval_nt

* ) +{d0 = d1 = 0;} + +template < bool P > +inline void init_double(double& d0, double& d1, double& d2, Interval_nt

* ) +{d0 = d1 = d2 = 0;} + +template < bool P > +inline void init_double(double& d0, double& d1, double& d2, double& d3, Interval_nt

* ) +{d0 = d1 = d2 = d3 = 0;} + +template < bool P > +inline void init_double(double& d0, double& d1, double& d2, double& d3, double& d4, Interval_nt

* ) +{d0 = d1 = d2 = d3 = d4 = 0;} + +template < bool P > +inline void init_double(double& d0, double& d1, double& d2, double& d3, double& d4, double& d5, Interval_nt

* ) +{d0 = d1 = d2 = d3 = d4 = d5 = 0;} + +template < bool P > +inline void init_double(double& d0, double& d1, double& d2, double& d3, double& d4, double& d5, double& d6, Interval_nt

* ) +{d0 = d1 = d2 = d3 = d4 = d5 = d6 = 0;} + +template < bool P > +inline void init_double(double& d0, double& d1, double& d2, double& d3, double& d4, double& d5, double& d6, double& d7, Interval_nt

* ) +{d0 = d1 = d2 = d3 = d4 = d5 = d6 = d7 = 0;} + +template < bool P > +inline void init_double(double& d0, double& d1, double& d2, double& d3, double& d4, double& d5, double& d6, double& d7, double& d8, Interval_nt

* ) +{d0 = d1 = d2 = d3 = d4 = d5 = d6 = d7 = d8 = 0;} + +template < bool P > +inline void init_double(double& d0, double& d1, double& d2, double& d3, double& d4, double& d5, double& d6, double& d7, double&d8, double& d9, Interval_nt

* ) +{d0 = d1 = d2 = d3 = d4 = d5 = d6 = d7 = d8 = d9 = 0;} + +template < bool P > +inline void init_double(double& d0, double& d1, double& d2, double& d3, double& d4, double& d5, double& d6, double& d7, double&d8, double& d9, double& d10, Interval_nt

* ) +{d0 = d1 = d2 = d3 = d4 = d5 = d6 = d7 = d8 = d9 = d10 = 0;} + +template < bool P > +inline void init_double(double& d0, double& d1, double& d2, double& d3, double& d4, double& d5, double& d6, double& d7, double&d8, double& d9, double& d10, double& d11, Interval_nt

* ) +{d0 = d1 = d2 = d3 = d4 = d5 = d6 = d7 = d8 = d9 = d10 = d11 = 0;} + +template < bool P > +inline void init_double(double& d0, double& d1, double& d2, double& d3, double& d4, double& d5, double& d6, double& d7, double&d8, double& d9, double& d10, double& d11, double& d12, Interval_nt

* ) +{d0 = d1 = d2 = d3 = d4 = d5 = d6 = d7 = d8 = d9 = d10 = d11 = d12 = 0;} + +template < bool P > +inline void init_double(double& d0, double& d1, double& d2, double& d3, double& d4, double& d5, double& d6, double& d7, double&d8, double& d9, double& d10, double& d11, double& d12, double& d13, Interval_nt

* ) +{d0 = d1 = d2 = d3 = d4 = d5 = d6 = d7 = d8 = d9 = d10 = d11 = d12 = d13 = 0;} + +template < bool P > +inline void init_double(double& d0, double& d1, double& d2, double& d3, double& d4, double& d5, double& d6, double& d7, double&d8, double& d9, double& d10, double& d11, double& d12, double& d13, double& d14, Interval_nt

* ) +{d0 = d1 = d2 = d3 = d4 = d5 = d6 = d7 = d8 = d9 = d10 = d11 = d12 = d13 = d14 = 0;} + // Auxiliary function to check if static filters can be applied, that is, // if to_double() does not add roundoff errors. diff --git a/Generalized_map/test/Generalized_map/Generalized_map_2_test.h b/Generalized_map/test/Generalized_map/Generalized_map_2_test.h index ff1ae0576f0..15274a323fa 100644 --- a/Generalized_map/test/Generalized_map/Generalized_map_2_test.h +++ b/Generalized_map/test/Generalized_map/Generalized_map_2_test.h @@ -24,9 +24,7 @@ #include #include -#include #include -#include using namespace std; diff --git a/Generator/doc/Generator/CGAL/Random_convex_set_traits_2.h b/Generator/doc/Generator/CGAL/Random_convex_set_traits_2.h index edae9a48042..4d866be8df9 100644 --- a/Generator/doc/Generator/CGAL/Random_convex_set_traits_2.h +++ b/Generator/doc/Generator/CGAL/Random_convex_set_traits_2.h @@ -26,26 +26,26 @@ typedef Kernel::FT FT; /*! function object class derived from -`CGAL::binary_function` +`CGAL::cpp98::binary_function` */ typedef unspecified_type Sum; /*! function object class derived from -`CGAL::binary_function` +`CGAL::cpp98::binary_function` */ typedef unspecified_type Scale; /*! function object class derived from -`CGAL::unary_function` +`CGAL::cpp98::unary_function` */ typedef unspecified_type Max_coordinate; /*! function object class derived from -`CGAL::binary_function` +`CGAL::cpp98::binary_function` */ typedef unspecified_type Angle_less; diff --git a/Generator/include/CGAL/Random_convex_set_traits_2.h b/Generator/include/CGAL/Random_convex_set_traits_2.h index 74378aa5314..c2b7770b790 100644 --- a/Generator/include/CGAL/Random_convex_set_traits_2.h +++ b/Generator/include/CGAL/Random_convex_set_traits_2.h @@ -46,7 +46,7 @@ struct Random_convex_set_traits_2 : public Kernel { { return _origin; } struct Max_coordinate - : public CGAL::unary_function< Point_2, FT > + : public CGAL::cpp98::unary_function< Point_2, FT > { FT operator()( const Point_2& p) const @@ -56,7 +56,7 @@ struct Random_convex_set_traits_2 : public Kernel { }; struct Sum - : public CGAL::binary_function< Point_2, Point_2, Point_2 > + : public CGAL::cpp98::binary_function< Point_2, Point_2, Point_2 > { Point_2 operator()( const Point_2& p, const Point_2& q) const @@ -64,7 +64,7 @@ struct Random_convex_set_traits_2 : public Kernel { }; struct Scale - : public CGAL::binary_function< Point_2, FT, Point_2 > + : public CGAL::cpp98::binary_function< Point_2, FT, Point_2 > { Point_2 operator()( const Point_2& p, const FT& k) const @@ -72,7 +72,7 @@ struct Random_convex_set_traits_2 : public Kernel { }; struct Angle_less - : public CGAL::binary_function< Point_2, Point_2, bool > + : public CGAL::cpp98::binary_function< Point_2, Point_2, bool > { bool operator()( const Point_2& p, const Point_2& q) const diff --git a/Generator/test/Generator/generic_random_test.cpp b/Generator/test/Generator/generic_random_test.cpp index d1c79fd0197..7ea066f4233 100644 --- a/Generator/test/Generator/generic_random_test.cpp +++ b/Generator/test/Generator/generic_random_test.cpp @@ -18,7 +18,6 @@ #include #include -#include #include #include @@ -50,11 +49,11 @@ typedef CGAL::Mesh_polyhedron_3::type Polyhedron; // Domain typedef CGAL::Polyhedral_mesh_domain_with_features_3 Mesh_domain; typedef Mesh_domain::Corner_index Corner_index; -typedef Mesh_domain::Curve_segment_index Curve_segment_index; +typedef Mesh_domain::Curve_index Curve_index; typedef CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3< - Tr, Corner_index, Curve_segment_index> C3t3; + Tr, Corner_index, Curve_index> C3t3; typedef CGAL::Mesh_criteria_3

Mesh_criteria; typedef C3t3::Point Point; diff --git a/GraphicsView/demo/Triangulation_2/CMakeLists.txt b/GraphicsView/demo/Triangulation_2/CMakeLists.txt index 5a5f7162e81..ed2ee61ef84 100644 --- a/GraphicsView/demo/Triangulation_2/CMakeLists.txt +++ b/GraphicsView/demo/Triangulation_2/CMakeLists.txt @@ -14,8 +14,6 @@ if(POLICY CMP0071) endif() set(CMAKE_AUTOMOC TRUE) -set(CMAKE_AUTOUIC TRUE) -set(CMAKE_AUTORCC TRUE) set(CMAKE_INCLUDE_CURRENT_DIR TRUE) find_package(CGAL COMPONENTS Qt5) @@ -32,9 +30,12 @@ add_definitions(-DQT_NO_KEYWORDS) # The "constrained Delaunay" demo: Constrained_Delaunay_triangulation_2 #-------------------------------- +qt5_add_resources ( CD_RES_FILE Constrained_Delaunay_triangulation_2.qrc) +qt5_wrap_ui( CD_UI_FILES Constrained_Delaunay_triangulation_2.ui) # The executable itself. add_executable( Constrained_Delaunay_triangulation_2 - Constrained_Delaunay_triangulation_2.cpp Constrained_Delaunay_triangulation_2.qrc) + Constrained_Delaunay_triangulation_2.cpp ${CD_UI_FILES} ${CGAL_Qt5_RESOURCE_FILES} + ${CD_RES_FILE}) target_link_libraries( Constrained_Delaunay_triangulation_2 PRIVATE CGAL::CGAL CGAL::CGAL_Qt5 Qt5::Widgets) target_include_directories( Constrained_Delaunay_triangulation_2 @@ -45,10 +46,11 @@ add_to_cached_list(CGAL_EXECUTABLE_TARGETS Constrained_Delaunay_triangulation_2) #-------------------------------- # The "Delaunay" demo: Delaunay_triangulation_2 #-------------------------------- - +qt5_wrap_ui( D_UI_FILES Delaunay_triangulation_2.ui) +qt5_add_resources ( D_RES_FILE Delaunay_triangulation_2.qrc) # The executable itself. add_executable ( Delaunay_triangulation_2 - Delaunay_triangulation_2.cpp Delaunay_triangulation_2.qrc) + Delaunay_triangulation_2.cpp ${D_UI_FILES} ${CGAL_Qt5_RESOURCE_FILES} ${D_RES_FILE}) target_link_libraries( Delaunay_triangulation_2 PRIVATE CGAL::CGAL CGAL::CGAL_Qt5 Qt5::Widgets) @@ -59,8 +61,10 @@ add_to_cached_list( CGAL_EXECUTABLE_TARGETS Delaunay_triangulation_2 ) #-------------------------------- # The executable itself. +qt5_add_resources ( R_RES_FILE Regular_triangulation_2.qrc) +qt5_wrap_ui(R_UI_FILES Regular_triangulation_2.ui) add_executable ( Regular_triangulation_2 - Regular_triangulation_2.cpp Regular_triangulation_2.qrc) + Regular_triangulation_2.cpp ${R_UI_FILES} ${CGAL_Qt5_RESOURCE_FILES} ${R_RES_FILE} ) target_link_libraries(Regular_triangulation_2 PRIVATE CGAL::CGAL CGAL::CGAL_Qt5 Qt5::Widgets) diff --git a/GraphicsView/demo/Triangulation_2/TriangulationCircumcircle.h b/GraphicsView/demo/Triangulation_2/TriangulationCircumcircle.h index 59589cf1815..dad56939a61 100644 --- a/GraphicsView/demo/Triangulation_2/TriangulationCircumcircle.h +++ b/GraphicsView/demo/Triangulation_2/TriangulationCircumcircle.h @@ -33,6 +33,7 @@ protected: private: DT * dt; + typedef typename DT::Vertex_handle Vertex_handle; typename DT::Vertex_handle hint; typename DT::Face_handle fh; QGraphicsScene *scene_; @@ -89,8 +90,12 @@ TriangulationCircumcircle::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { if(dt->dimension() != 2){ circle->hide(); + hint = Vertex_handle(); return; } + if (hint == Vertex_handle()){ + hint = dt->infinite_vertex(); + } typename T::Point p = typename T::Point(event->scenePos().x(), event->scenePos().y()); fh = dt->locate(p, hint->face()); hint = fh->vertex(0); diff --git a/GraphicsView/include/CGAL/Buffer_for_vao.h b/GraphicsView/include/CGAL/Buffer_for_vao.h new file mode 100644 index 00000000000..b8ca1f752bb --- /dev/null +++ b/GraphicsView/include/CGAL/Buffer_for_vao.h @@ -0,0 +1,800 @@ +// Copyright (c) 2018 GeometryFactory Sarl (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// +// Author(s) : Guillaume Damiand + +#ifndef CGAL_VBO_BUFFER_FILLER_H +#define CGAL_VBO_BUFFER_FILLER_H + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +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 +{ + template + void newell_single_step_3(const Point& p, const Point& q, Vector& n) + { + // Compute normal of the face by using Newell's method: for each edge PQ + // Nx += (Py - Qy) * (Pz + Qz); + // Ny += (Pz - Qz) * (Px + Qx); + // Nz += (Px - Qx) * (Py + Qy); + n = Vector(n.x()+((p.y()-q.y())*(p.z()+q.z())), + n.y()+((p.z()-q.z())*(p.x()+q.x())), + n.z()+((p.x()-q.x())*(p.y()+q.y()))); + } + + inline + Local_vector compute_normal_of_face(const std::vector& points) + { + Local_vector normal(CGAL::NULL_VECTOR); + unsigned int nb = 0; + for (std::size_t i=0; i0); + return (Local_kernel::Construct_scaled_vector_3()(normal, 1.0/nb)); + } + + //////////////////////////////////////////////////////////////// + // Structs to transform any CGAL point/vector into a Local_point/Local_vector + template + struct Geom_utils + { + static Local_point get_local_point(const typename K::Point_2& p) + { + CGAL::Cartesian_converter converter; + return Local_point(converter(p.x()), 0, converter(p.y())); + } + static Local_point get_local_point(const typename K::Weighted_point_2& p) + { + typename K::Point_2 lp(p); + return Geom_utils::get_local_point(lp); + } + static Local_point get_local_point(const typename K::Point_3& p) + { + CGAL::Cartesian_converter converter; + return converter(p); + } + static Local_point get_local_point(const typename K::Weighted_point_3& p) + { + typename K::Point_3 lp(p); + return Geom_utils::get_local_point(lp); + } + static Local_vector get_local_vector(const typename K::Vector_2& v) + { + CGAL::Cartesian_converter converter; + return Local_vector(converter(v.x()), 0, converter(v.y())); + } + static Local_vector get_local_vector(const typename K::Vector_3& v) + { + CGAL::Cartesian_converter converter; + return converter(v); + } + }; + + // Specialization for Local_kernel, because there is no need of convertion here. + template<> + struct Geom_utils + { + static Local_point get_local_point(const Local_kernel::Point_2& p) + { return Local_point(p.x(), 0, p.y()); } + static Local_point get_local_point(const Local_kernel::Weighted_point_2& p) + { return Local_point(p.point().x(), 0, p.point().y());} + static const Local_point & get_local_point(const Local_kernel::Point_3& p) + { return p; } + static Local_point get_local_point(const Local_kernel::Weighted_point_3& p) + { return Local_point(p);} + static Local_vector get_local_vector(const Local_kernel::Vector_2& v) + { return Local_vector(v.x(), 0, v.y()); } + static const Local_vector& get_local_vector(const Local_kernel::Vector_3& v) + { return v; } + }; + + //////////////////////////////////////////////////////////////// + // Global function to simplify function calls. + template + Local_point get_local_point(const KPoint& p) + { + return Geom_utils::Kernel>:: + get_local_point(p); + } + template + Local_vector get_local_vector(const KVector& v) + { + return Geom_utils::Kernel>:: + get_local_vector(v); + } +} // End namespace internal + +//------------------------------------------------------------------------------ +template +class Buffer_for_vao +{ +public: + Buffer_for_vao(std::vector* pos=NULL, + std::vector* indices=NULL, + CGAL::Bbox_3* bbox=NULL, + std::vector* color=NULL, + std::vector* flat_normal=NULL, + std::vector* gouraud_normal=NULL) : + m_pos_buffer(pos), + m_index_buffer(indices), + m_color_buffer(color), + m_flat_normal_buffer(flat_normal), + m_gouraud_normal_buffer(gouraud_normal), + m_bb(bbox), + m_face_started(false) + {} + + void clear() + { + if (m_pos_buffer!=NULL) { m_pos_buffer->clear(); } + if (m_color_buffer!=NULL) { m_color_buffer->clear(); } + if (m_index_buffer!=NULL) { m_index_buffer->clear(); } + if (m_flat_normal_buffer!=NULL) { m_flat_normal_buffer->clear(); } + if (m_gouraud_normal_buffer!=NULL) { m_gouraud_normal_buffer->clear(); } + } + + bool is_empty() const + { + return + (m_pos_buffer!=NULL && m_pos_buffer->empty()) && + (m_color_buffer!=NULL || m_color_buffer->empty()) && + (m_flat_normal_buffer!=NULL || m_flat_normal_buffer->empty()) && + (m_gouraud_normal_buffer!=NULL || m_gouraud_normal_buffer->empty()) && + (m_index_buffer!=NULL || m_index_buffer->empty()); + } + + bool has_position() const + { return m_pos_buffer!=NULL; } + + bool has_indices() const + { return m_index_buffer!=NULL; } + + bool has_color() const + { return m_color_buffer!=NULL; } + + bool has_flat_normal() const + { return m_flat_normal_buffer!=NULL; } + + bool has_gouraud_normal() const + { return m_gouraud_normal_buffer!=NULL; } + + // 1.1) Add a point, without color. Return the index of the added point. + template + std::size_t add_point(const KPoint& kp) + { + if (!has_position()) return (std::size_t)-1; + + Local_point p=internal::get_local_point(kp); + add_point_in_buffer(p, *m_pos_buffer); + + if (m_bb!=NULL) + { (*m_bb)=(*m_bb)+p.bbox(); } + + return m_pos_buffer->size()-3; + } + + // 1.2) Add a point, with color. + template + void add_point(const KPoint& kp, const CGAL::Color& c) + { + add_point(kp); + add_color(c); + } + + // 1.3) Add an indexed point, without color. + template + void add_indexed_point(T index) + { + if (!has_indices()) return; + m_index_buffer->push_back((IndexType)index); + } + + // 2.1) Add a segment, without color. + template + void add_segment(const KPoint& kp1, const KPoint& kp2) + { + add_point(kp1); + add_point(kp2); + } + + // 2.2) Add a segment, with color. + template + void add_segment(const KPoint& kp1, const KPoint& kp2, const CGAL::Color& c) + { + add_segment(kp1, kp2); + add_color(c); + add_color(c); + } + + // 2.3) Add an indexed segment, without color. + template + void add_indexed_segment(T index1, T index2) + { + add_indexed_point(index1); + add_indexed_point(index2); + } + + /// @return true iff a face has begun. + bool is_a_face_started() const + { return m_face_started; } + + // 3.1) Add a face, without color, without normal. + void face_begin() + { face_begin_internal(false, false); } + + // 3.2) Add a face, with a color, without normal. + void face_begin(const CGAL::Color& c) + { + m_color_of_face=c; + face_begin_internal(true, false); + } + + // 3.3) Add a face, without a color, with a normal. + template + void face_begin(const KNormal& kv) + { + m_normal_of_face=internal::get_local_vector(kv); + face_begin_internal(false, true); + } + + // 3.3) Add a face, with a color and with a normal. + template + void face_begin(const CGAL::Color& c, const KNormal& kv) + { + m_color_of_face=c; + m_normal_of_face=internal::get_local_vector(kv); + face_begin_internal(true, true); + } + + /// Add a point at the end of the current face, without giving the vertex normal. + /// When this method is used, it is not possible to use the Gouraud shading. + /// @param p the point to add + template + bool add_point_in_face(const KPoint& kp) + { + if (!is_a_face_started()) return false; + + Local_point p=internal::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 ??) + { + m_points_of_face.push_back(p); + return true; + } + return false; + } + + /// Add a point at the end of the current face + /// @param p the point to add + /// @p_normal the vertex normal at this point (for Gouraud shading) + template + bool add_point_in_face(const KPoint& kp, const KVector& p_normal) + { + if (add_point_in_face(kp)) + { + m_vertex_normals_for_face.push_back(internal::get_local_vector(p_normal)); + return true; + } + return false; + } + + /// Add an indexed point at the end of the current face, without giving the vertex normal. + /// When Indexation is used, it is not possible to use flat shading or multiple colors + /// for face sor edges. + /// Note that we still need the point itself, in order to triangulate the face when necessary. + template + bool add_indexed_point_in_face(T index, const KPoint& kp) + { + if (add_point_in_face(kp)) + { + m_indices_of_points_of_face.push_back(index); + return true; + } + return false; + } + + /// End the face: compute the triangulation. + void face_end() + { + if (!is_a_face_started()) return; + + if (m_points_of_face.size()<3) + { + std::cerr<<"PB: you try to triangulate a face with "<0 && + m_indices_of_points_of_face.size()!=m_points_of_face.size()) + { + std::cerr<<"PB: you mixed some add_point_in_face(...) and some add_indexed_point_in_face(...)" + <<" for a same face. Indices for this face are ignored."<0 && + m_vertex_normals_for_face.size()!=m_points_of_face.size()) + { + std::cerr<<"PB: you only gave some vertex normals (and not all) for a same face. " + <<"All vertex normal are ignored and thus it is not possible to use Gouraud " + <<"shading for this face." + < 4 vertices + } + else + { // Non convex and more than 3 points: we triangulate + nonconvex_face_end_internal(normal); + } + + m_face_started=false; + } + + /// adds `kp` coordinates to `buffer` + template + static void add_point_in_buffer(const KPoint& kp, std::vector& buffer) + { + Local_point p=internal::get_local_point(kp); + buffer.push_back(p.x()); + buffer.push_back(p.y()); + buffer.push_back(p.z()); + } + + /// adds `kv` coordinates to `buffer` + template + static void add_normal_in_buffer(const KVector& kv, std::vector& buffer) + { + Local_vector n=internal::get_local_vector(kv); + buffer.push_back(n.x()); + buffer.push_back(n.y()); + buffer.push_back(n.z()); + } + + ///adds `acolor` RGB components to `buffer` + static void add_color_in_buffer(const CGAL::Color& acolor, std::vector& buffer) + { + buffer.push_back((float)acolor.red()/(float)255); + buffer.push_back((float)acolor.green()/(float)255); + buffer.push_back((float)acolor.blue()/(float)255); + } + + /// @return true iff the points of 'facet' form a convex face + static bool is_facet_convex(const std::vector& facet, + const Local_vector& normal) + { + Local_kernel::Orientation orientation, local_orientation; + std::size_t id=0; + do + { + const Local_point& S=facet[id]; + const Local_point& T=facet[(id+1==facet.size())?0:id+1]; + Local_vector V1=Local_vector((T-S).x(), (T-S).y(), (T-S).z()); + + const Local_point& U=facet[(id+2==facet.size())?0:id+2]; + Local_vector V2=Local_vector((U-T).x(), (U-T).y(), (U-T).z()); + + orientation = Local_kernel::Orientation_3()(V1, V2, normal); + // Is it possible that orientation==COPLANAR ? Maybe if V1 or V2 is very small ? + } + while(++id!=facet.size() && + (orientation==CGAL::COPLANAR || orientation==CGAL::ZERO)); + + //Here, all orientations were COPLANAR. Not sure this case is possible, + // but we stop here. + if (orientation==CGAL::COPLANAR || orientation==CGAL::ZERO) + { return false; } + + // Now we compute convexness + for(id=0; id0) + { + add_indexed_point(m_indices_of_points_of_face[i]); + } + else + { + add_point(m_points_of_face[i]); // Add the position of the point + if (m_started_face_is_colored) + { add_color(m_color_of_face); } // Add the color + add_flat_normal(normal); // Add the flat normal + // Its smooth normal (if given by the user) + if (m_vertex_normals_for_face.size()>0) + { // Here we have 3 vertex normals; we can use Gouraud + add_gouraud_normal(m_vertex_normals_for_face[i]); + } + else + { // Here user does not provide all vertex normals: we use face normal istead + // and thus we will not be able to use Gouraud + add_gouraud_normal(normal); + } + } + } + } + + void convex_quadrangular_face_end_internal(const Local_vector& normal) + { + // Add indices when they exist + if (m_indices_of_points_of_face.size()>0) + { + add_indexed_point(m_indices_of_points_of_face[0]); + add_indexed_point(m_indices_of_points_of_face[1]); + add_indexed_point(m_indices_of_points_of_face[2]); + + add_indexed_point(m_indices_of_points_of_face[0]); + add_indexed_point(m_indices_of_points_of_face[2]); + add_indexed_point(m_indices_of_points_of_face[3]); + } + else + { + // (1) add points + add_point(m_points_of_face[0]); + add_point(m_points_of_face[1]); + add_point(m_points_of_face[2]); + + add_point(m_points_of_face[0]); + add_point(m_points_of_face[2]); + add_point(m_points_of_face[3]); + + // (2) Add flat and smooth normals and color + for(unsigned int i=0; i<6; ++i) + { + if (m_started_face_is_colored) + { add_color(m_color_of_face); } + + add_flat_normal(normal); + + if (m_vertex_normals_for_face.size()==0) + { add_gouraud_normal(normal); } + } + + if (m_vertex_normals_for_face.size()>0) + { + add_gouraud_normal(m_vertex_normals_for_face[0]); + add_gouraud_normal(m_vertex_normals_for_face[1]); + add_gouraud_normal(m_vertex_normals_for_face[2]); + + add_gouraud_normal(m_vertex_normals_for_face[0]); + add_gouraud_normal(m_vertex_normals_for_face[2]); + add_gouraud_normal(m_vertex_normals_for_face[3]); + } + } + } + + void convex_face_end_internal(const Local_vector& normal) + { + for(std::size_t i=1; i0) + { + add_indexed_point(m_indices_of_points_of_face[0]); + add_indexed_point(m_indices_of_points_of_face[i]); + add_indexed_point(m_indices_of_points_of_face[i+1]); + } + else + { + Local_point& p0 = m_points_of_face[0]; + Local_point& p1 = m_points_of_face[i]; + Local_point& p2 = m_points_of_face[i+1]; + + // (1) add points + add_point(p0); + add_point(p1); + add_point(p2); + + // (2) Add flat normal and color + for(unsigned int j=0; j<3; ++j) + { + if (m_started_face_is_colored) + { add_color(m_color_of_face); } + + add_flat_normal(normal); + + if (m_vertex_normals_for_face.size()==0) + { add_gouraud_normal(normal); } // No smooth normal, we use the flat one instead + } + + // (3) Add smooth normals if they exist + if (m_vertex_normals_for_face.size()>0) + { + add_gouraud_normal(m_vertex_normals_for_face[0]); + add_gouraud_normal(m_vertex_normals_for_face[i]); + add_gouraud_normal(m_vertex_normals_for_face[i+1]); + } + } + } + } + + void nonconvex_face_end_internal(const Local_vector& normal) + { + try + { + P_traits cdt_traits(normal); + CDT cdt(cdt_traits); + + bool with_vertex_normal=(m_vertex_normals_for_face.size()==m_points_of_face.size()); + + // (1) We insert all the edges as contraint in the CDT. + typename CDT::Vertex_handle previous=NULL, first=NULL; + for (unsigned int i=0; iinfo().v=m_vertex_normals_for_face[i]; } + else + { vh->info().v=normal; } + + if (m_indices_of_points_of_face.size()>0) + { vh->info().index=m_indices_of_points_of_face[i]; } + + if(previous!=NULL && previous!=vh) + { cdt.insert_constraint(previous, vh); } + previous=vh; + } + + if (previous!=NULL && previous!=first) + { cdt.insert_constraint(previous, first); } + + // (2) We mark all external triangles + // (2.1) We initialize is_external and is_process values + for(typename CDT::All_faces_iterator fit = cdt.all_faces_begin(), + fitend = cdt.all_faces_end(); fit!=fitend; ++fit) + { + fit->info().is_external = true; + fit->info().is_process = false; + } + // (2.2) We check if the facet is external or internal + std::queue face_queue; + typename CDT::Face_handle face_internal = NULL; + if (cdt.infinite_vertex()->face()!=NULL) + { face_queue.push(cdt.infinite_vertex()->face()); } + while(!face_queue.empty()) + { + typename CDT::Face_handle fh = face_queue.front(); + face_queue.pop(); + if(!fh->info().is_process) + { + fh->info().is_process = true; + for(int i=0; i<3; ++i) + { + if(!cdt.is_constrained(std::make_pair(fh, i))) + { + if (fh->neighbor(i)!=NULL) + { face_queue.push(fh->neighbor(i)); } + } + else if (face_internal==NULL) + { + face_internal = fh->neighbor(i); + } + } + } + } + + if ( face_internal!=NULL ) + { face_queue.push(face_internal); } + + while(!face_queue.empty()) + { + typename CDT::Face_handle fh = face_queue.front(); + face_queue.pop(); + if(!fh->info().is_process) + { + fh->info().is_process = true; + fh->info().is_external = false; + for(unsigned int i=0; i<3; ++i) + { + if(!cdt.is_constrained(std::make_pair(fh, i))) + { + if (fh->neighbor(i)!=NULL) + { face_queue.push(fh->neighbor(i)); } + } + } + } + } + + // (3) Now we iterates on the internal faces to add the vertices + // and the normals to the appropriate vectors + for(typename CDT::Finite_faces_iterator ffit=cdt.finite_faces_begin(), + ffitend = cdt.finite_faces_end(); ffit!=ffitend; ++ffit) + { + if(!ffit->info().is_external) + { + for(unsigned int i=0; i<3; ++i) + { + // Add indices when they exist + if (m_indices_of_points_of_face.size()>0) + { add_indexed_point(ffit->vertex(i)->info().index); } + else + { + // (1) add point + add_point(ffit->vertex(i)->point()); + // (2) Add face color + if (m_started_face_is_colored) + { add_color(m_color_of_face); } + + // (3) Add flat normal + add_flat_normal(normal); + + // (4) Add smooth normals (or flat if smooth normals do not exist) + add_gouraud_normal(ffit->vertex(i)->info().v); + } + } + } + } + } + catch(...) + { // Triangulation crash: the face is not filled + std::cerr<<"Catch: face not filled."< + void add_flat_normal(const KVector& kv) + { + if(m_flat_normal_buffer != NULL) + { add_normal_in_buffer(kv, *m_flat_normal_buffer); } + } + + template + void add_gouraud_normal(const KVector& kv) + { + if(m_gouraud_normal_buffer != NULL) + { add_normal_in_buffer(kv, *m_gouraud_normal_buffer); } + } + +protected: + // Types usefull for triangulation + struct Vertex_info + { + Local_vector v; + std::size_t index; + }; + + struct Face_info + { + bool exist_edge[3]; + bool is_external; + bool is_process; + }; + + typedef CGAL::Triangulation_2_projection_traits_3 P_traits; + typedef CGAL::Triangulation_vertex_base_with_info_2 Vb; + typedef CGAL::Triangulation_face_base_with_info_2 Fb1; + typedef CGAL::Constrained_triangulation_face_base_2 Fb; + typedef CGAL::Triangulation_data_structure_2 TDS; + typedef CGAL::Exact_predicates_tag Itag; + typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; + +protected: + std::vector* m_pos_buffer; + std::vector* m_index_buffer; + std::vector* m_color_buffer; + std::vector* m_flat_normal_buffer; + std::vector* m_gouraud_normal_buffer; + + CGAL::Bbox_3* m_bb; + + // Local variables, used when we started a new face. + bool m_face_started; + bool m_started_face_is_colored; + bool m_started_face_has_normal; + std::vector m_points_of_face; + std::vector m_vertex_normals_for_face; + std::vector m_indices_of_points_of_face; + CGAL::Color m_color_of_face; + Local_vector m_normal_of_face; +}; + +} // End namespace CGAL + +#endif // CGAL_VBO_BUFFER_FILLER_H diff --git a/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h b/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h new file mode 100644 index 00000000000..dcf9168521d --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h @@ -0,0 +1,1081 @@ +// Copyright (c) 2018 GeometryFactory Sarl (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// +// Author(s) : Guillaume Damiand + +#ifndef CGAL_BASIC_VIEWER_QT_H +#define CGAL_BASIC_VIEWER_QT_H + +#include +#include + +#ifdef CGAL_USE_BASIC_VIEWER + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +namespace CGAL +{ + +//------------------------------------------------------------------------------ +const char vertex_source_color[] = + { + "#version 120 \n" + "attribute highp vec4 vertex;\n" + "attribute highp vec3 normal;\n" + "attribute highp vec3 color;\n" + + "uniform highp mat4 mvp_matrix;\n" + "uniform highp mat4 mv_matrix; \n" + + "varying highp vec4 fP; \n" + "varying highp vec3 fN; \n" + "varying highp vec4 fColor; \n" + "void main(void)\n" + "{\n" + " fP = mv_matrix * vertex; \n" + " fN = mat3(mv_matrix)* normal; \n" + " fColor = vec4(color, 1.0); \n" + " gl_Position = mvp_matrix * vertex;\n" + "}" + }; + +const char fragment_source_color[] = + { + "#version 120 \n" + "varying highp vec4 fP; \n" + "varying highp vec3 fN; \n" + "varying highp vec4 fColor; \n" + "uniform vec4 light_pos; \n" + "uniform vec4 light_diff; \n" + "uniform vec4 light_spec; \n" + "uniform vec4 light_amb; \n" + "uniform float spec_power ; \n" + + "void main(void) { \n" + + " vec3 L = light_pos.xyz - fP.xyz; \n" + " vec3 V = -fP.xyz; \n" + + " vec3 N = normalize(fN); \n" + " L = normalize(L); \n" + " V = normalize(V); \n" + + " vec3 R = reflect(-L, N); \n" + " vec4 diffuse = max(dot(N,L), 0.0) * light_diff * fColor; \n" + " vec4 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; \n" + + "gl_FragColor = light_amb*fColor + diffuse ; \n" + "} \n" + "\n" + }; + +const char vertex_source_p_l[] = + { + "#version 120 \n" + "attribute highp vec4 vertex;\n" + "attribute highp vec3 color;\n" + "uniform highp mat4 mvp_matrix;\n" + "varying highp vec4 fColor; \n" + "void main(void)\n" + "{\n" + " fColor = vec4(color, 1.0); \n" + " gl_Position = mvp_matrix * vertex;\n" + "}" + }; + +const char fragment_source_p_l[] = + { + "#version 120 \n" + "varying highp vec4 fColor; \n" + "void main(void) { \n" + "gl_FragColor = fColor; \n" + "} \n" + "\n" + }; +//------------------------------------------------------------------------------ +inline CGAL::Color get_random_color(CGAL::Random& random) +{ + CGAL::Color res; + do + { + res=CGAL::Color(random.get_int(0,256), + random.get_int(0,256), + random.get_int(0,256)); + } + while(res.red()==255 && res.green()==255 && res.blue()==255); + return res; +} +//------------------------------------------------------------------------------ +class Basic_viewer_qt : public CGAL::QGLViewer +{ + typedef CGAL::Exact_predicates_inexact_constructions_kernel Local_kernel; + typedef Local_kernel::Point_3 Local_point; + typedef Local_kernel::Vector_3 Local_vector; + +public: + // Constructor/Destructor + Basic_viewer_qt(QWidget* parent, + const char* title="", + bool draw_vertices=false, + bool draw_edges=true, + bool draw_faces=true, + bool use_mono_color=false, + bool inverse_normal=false) : + CGAL::QGLViewer(parent), + m_draw_vertices(draw_vertices), + m_draw_edges(draw_edges), + m_draw_faces(draw_faces), + m_flatShading(true), + m_use_mono_color(use_mono_color), + m_inverse_normal(inverse_normal), + m_size_points(7.), + m_size_edges(3.1), + m_vertices_mono_color(200, 60, 60), + m_edges_mono_color(0, 0, 0), + m_faces_mono_color(60, 60, 200), + m_ambient_color(0.6f, 0.5f, 0.5f, 0.5f), + m_are_buffers_initialized(false), + m_buffer_for_mono_points(&arrays[POS_MONO_POINTS], + NULL, + &m_bounding_box, + NULL, NULL, NULL), + m_buffer_for_colored_points(&arrays[POS_COLORED_POINTS], + NULL, + &m_bounding_box, + &arrays[COLOR_POINTS], + NULL, NULL), + m_buffer_for_mono_segments(&arrays[POS_MONO_SEGMENTS], + NULL, + &m_bounding_box, + NULL, NULL, NULL), + m_buffer_for_colored_segments(&arrays[POS_COLORED_SEGMENTS], + NULL, + &m_bounding_box, + &arrays[COLOR_SEGMENTS], + NULL, NULL), + m_buffer_for_mono_faces(&arrays[POS_MONO_FACES], + NULL, + &m_bounding_box, + NULL, + &arrays[FLAT_NORMAL_MONO_FACES], + &arrays[SMOOTH_NORMAL_MONO_FACES]), + m_buffer_for_colored_faces(&arrays[POS_COLORED_FACES], + NULL, + &m_bounding_box, + &arrays[COLOR_FACES], + &arrays[FLAT_NORMAL_COLORED_FACES], + &arrays[SMOOTH_NORMAL_COLORED_FACES]) + { + if (title[0]==0) + setWindowTitle("CGAL Basic Viewer"); + else + setWindowTitle(title); + + resize(500, 450); + } + + ~Basic_viewer_qt() + { + for (unsigned int i=0; i + void add_point(const KPoint& p) + { m_buffer_for_mono_points.add_point(p); } + + template + void add_point(const KPoint& p, const CGAL::Color& acolor) + { m_buffer_for_colored_points.add_point(p, acolor); } + + template + void add_segment(const KPoint& p1, const KPoint& p2) + { m_buffer_for_mono_segments.add_segment(p1, p2); } + + template + void add_segment(const KPoint& p1, const KPoint& p2, + const CGAL::Color& acolor) + { m_buffer_for_colored_segments.add_segment(p1, p2, acolor); } + + bool is_a_face_started() const + { + return m_buffer_for_mono_faces.is_a_face_started() || + m_buffer_for_colored_faces.is_a_face_started(); + } + + void face_begin() + { + if (is_a_face_started()) + { + std::cerr<<"You cannot start a new face before to finish the previous one."< + bool add_point_in_face(const KPoint& kp) + { + if (m_buffer_for_mono_faces.is_a_face_started()) + { return m_buffer_for_mono_faces.add_point_in_face(kp); } + else if (m_buffer_for_colored_faces.is_a_face_started()) + { return m_buffer_for_colored_faces.add_point_in_face(kp); } + return false; + } + + template + bool add_point_in_face(const KPoint& kp, const KVector& p_normal) + { + if (m_buffer_for_mono_faces.is_a_face_started()) + { return m_buffer_for_mono_faces.add_point_in_face(kp, p_normal); } + else if (m_buffer_for_colored_faces.is_a_face_started()) + { return m_buffer_for_colored_faces.add_point_in_face(kp, p_normal); } + return false; + } + + void face_end() + { + if (m_buffer_for_mono_faces.is_a_face_started()) + { m_buffer_for_mono_faces.face_end(); } + else if (m_buffer_for_colored_faces.is_a_face_started()) + { return m_buffer_for_colored_faces.face_end(); } + } + +protected: + void compile_shaders() + { + rendering_program_face.removeAllShaders(); + rendering_program_p_l.removeAllShaders(); + + // Create the buffers + for (unsigned int i=0; icompileSourceCode(vertex_source_p_l)) + { std::cerr<<"Compiling vertex source FAILED"<compileSourceCode(fragment_source_p_l)) + { std::cerr<<"Compiling fragmentsource FAILED"<compileSourceCode(vertex_source_color)) + { std::cerr<<"Compiling vertex source FAILED"<compileSourceCode(fragment_source_color)) + { std::cerr<<"Compiling fragmentsource FAILED"<(arrays[POS_MONO_POINTS].size()*sizeof(float))); + rendering_program_p_l.enableAttributeArray("vertex"); + rendering_program_p_l.setAttributeBuffer("vertex",GL_FLOAT,0,3); + + buffers[bufn].release(); + + rendering_program_p_l.disableAttributeArray("color"); + + vao[VAO_MONO_POINTS].release(); + + // 1.2) Color points + vao[VAO_COLORED_POINTS].bind(); + + ++bufn; + assert(bufn(arrays[POS_COLORED_POINTS].size()*sizeof(float))); + rendering_program_p_l.enableAttributeArray("vertex"); + rendering_program_p_l.setAttributeBuffer("vertex",GL_FLOAT,0,3); + buffers[bufn].release(); + + ++bufn; + assert(bufn(arrays[COLOR_POINTS].size()*sizeof(float))); + rendering_program_p_l.enableAttributeArray("color"); + rendering_program_p_l.setAttributeBuffer("color",GL_FLOAT,0,3); + buffers[bufn].release(); + + vao[VAO_COLORED_POINTS].release(); + + // 2) SEGMENT SHADER + + // 2.1) Mono segments + vao[VAO_MONO_SEGMENTS].bind(); + + ++bufn; + assert(bufn(arrays[POS_MONO_SEGMENTS].size()*sizeof(float))); + rendering_program_p_l.enableAttributeArray("vertex"); + rendering_program_p_l.setAttributeBuffer("vertex",GL_FLOAT,0,3); + + buffers[bufn].release(); + + rendering_program_p_l.disableAttributeArray("color"); + + vao[VAO_MONO_SEGMENTS].release(); + + // 1.2) Color segments + vao[VAO_COLORED_SEGMENTS].bind(); + + ++bufn; + assert(bufn(arrays[POS_COLORED_SEGMENTS].size()*sizeof(float))); + rendering_program_p_l.enableAttributeArray("vertex"); + rendering_program_p_l.setAttributeBuffer("vertex",GL_FLOAT,0,3); + + buffers[bufn].release(); + + ++bufn; + assert(bufn(arrays[COLOR_SEGMENTS].size()*sizeof(float))); + rendering_program_p_l.enableAttributeArray("color"); + rendering_program_p_l.setAttributeBuffer("color",GL_FLOAT,0,3); + buffers[bufn].release(); + + vao[VAO_COLORED_SEGMENTS].release(); + + rendering_program_p_l.release(); + + // 3) FACE SHADER + rendering_program_face.bind(); + + // 3.1) Mono faces + vao[VAO_MONO_FACES].bind(); + + // 3.1.1) points of the mono faces + ++bufn; + assert(bufn(arrays[POS_MONO_FACES].size()*sizeof(float))); + rendering_program_face.enableAttributeArray("vertex"); + rendering_program_face.setAttributeBuffer("vertex",GL_FLOAT,0,3); + + buffers[bufn].release(); + + // 3.1.2) normals of the mono faces + ++bufn; + assert(bufn(arrays[FLAT_NORMAL_MONO_FACES].size()* + sizeof(float))); + } + else + { + buffers[bufn].allocate(arrays[SMOOTH_NORMAL_MONO_FACES].data(), + static_cast(arrays[SMOOTH_NORMAL_MONO_FACES].size()* + sizeof(float))); + } + rendering_program_face.enableAttributeArray("normal"); + rendering_program_face.setAttributeBuffer("normal",GL_FLOAT,0,3); + + buffers[bufn].release(); + + // 3.1.3) color of the mono faces + rendering_program_face.disableAttributeArray("color"); + vao[VAO_MONO_FACES].release(); + + // 3.2) Color faces + vao[VAO_COLORED_FACES].bind(); + + // 3.2.1) points of the color faces + ++bufn; + assert(bufn(arrays[POS_COLORED_FACES].size()*sizeof(float))); + rendering_program_face.enableAttributeArray("vertex"); + rendering_program_face.setAttributeBuffer("vertex",GL_FLOAT,0,3); + + buffers[bufn].release(); + + // 3.2.2) normals of the color faces + ++bufn; + assert(bufn(arrays[FLAT_NORMAL_COLORED_FACES].size()* + sizeof(float))); + } + else + { + buffers[bufn].allocate(arrays[SMOOTH_NORMAL_COLORED_FACES].data(), + static_cast(arrays[SMOOTH_NORMAL_COLORED_FACES].size()* + sizeof(float))); + } + rendering_program_face.enableAttributeArray("normal"); + rendering_program_face.setAttributeBuffer("normal",GL_FLOAT,0,3); + + buffers[bufn].release(); + + // 3.2.3) colors of the faces + ++bufn; + assert(bufn(arrays[COLOR_FACES].size()*sizeof(float))); + rendering_program_face.enableAttributeArray("color"); + rendering_program_face.setAttributeBuffer("color",GL_FLOAT,0,3); + + buffers[bufn].release(); + + vao[VAO_COLORED_FACES].release(); + + rendering_program_face.release(); + + m_are_buffers_initialized = true; + } + + void attrib_buffers(CGAL::QGLViewer* viewer) + { + QMatrix4x4 mvpMatrix; + QMatrix4x4 mvMatrix; + double mat[16]; + viewer->camera()->getModelViewProjectionMatrix(mat); + for(int i=0; i < 16; i++) + { + mvpMatrix.data()[i] = (float)mat[i]; + } + viewer->camera()->getModelViewMatrix(mat); + for(int i=0; i < 16; i++) + { + mvMatrix.data()[i] = (float)mat[i]; + } + // define material + QVector4D diffuse( 0.9f, + 0.9f, + 0.9f, + 0.9f ); + + QVector4D specular( 0.0f, + 0.0f, + 0.0f, + 1.0f ); + + CGAL::Bbox_3 bb; + if (bb==bounding_box()) // Case of "empty" bounding box + { + bb=Local_point(CGAL::ORIGIN).bbox(); + bb=bb + Local_point(1,1,1).bbox(); // To avoid a warning from Qglviewer + } + else + { bb=bounding_box(); } + + QVector4D position((bb.xmax()-bb.xmin())/2, + (bb.ymax()-bb.ymin())/2, + bb.zmax(), 0.0); + GLfloat shininess = 1.0f; + + rendering_program_face.bind(); + int mvpLocation = rendering_program_face.uniformLocation("mvp_matrix"); + int mvLocation = rendering_program_face.uniformLocation("mv_matrix"); + int lightLocation[5]; + lightLocation[0] = rendering_program_face.uniformLocation("light_pos"); + lightLocation[1] = rendering_program_face.uniformLocation("light_diff"); + lightLocation[2] = rendering_program_face.uniformLocation("light_spec"); + lightLocation[3] = rendering_program_face.uniformLocation("light_amb"); + lightLocation[4] = rendering_program_face.uniformLocation("spec_power"); + + rendering_program_face.setUniformValue(lightLocation[0], position); + rendering_program_face.setUniformValue(lightLocation[1], diffuse); + rendering_program_face.setUniformValue(lightLocation[2], specular); + rendering_program_face.setUniformValue(lightLocation[3], m_ambient_color); + rendering_program_face.setUniformValue(lightLocation[4], shininess); + rendering_program_face.setUniformValue(mvpLocation, mvpMatrix); + rendering_program_face.setUniformValue(mvLocation, mvMatrix); + rendering_program_face.release(); + + rendering_program_p_l.bind(); + int mvpLocation2 = rendering_program_p_l.uniformLocation("mvp_matrix"); + rendering_program_p_l.setUniformValue(mvpLocation2, mvpMatrix); + rendering_program_p_l.release(); + } + + virtual void draw() + { + glEnable(GL_DEPTH_TEST); + if(!m_are_buffers_initialized) + { initialize_buffers(); } + + QColor color; + attrib_buffers(this); + + if(m_draw_vertices) + { + rendering_program_p_l.bind(); + + vao[VAO_MONO_POINTS].bind(); + color.setRgbF((double)m_vertices_mono_color.red()/(double)255, + (double)m_vertices_mono_color.green()/(double)255, + (double)m_vertices_mono_color.blue()/(double)255); + rendering_program_p_l.setAttributeValue("color",color); + glPointSize(m_size_points); + glDrawArrays(GL_POINTS, 0, static_cast(arrays[POS_MONO_POINTS].size()/3)); + vao[VAO_MONO_POINTS].release(); + + vao[VAO_COLORED_POINTS].bind(); + if (m_use_mono_color) + { + color.setRgbF((double)m_vertices_mono_color.red()/(double)255, + (double)m_vertices_mono_color.green()/(double)255, + (double)m_vertices_mono_color.blue()/(double)255); + rendering_program_p_l.disableAttributeArray("color"); + rendering_program_p_l.setAttributeValue("color",color); + } + else + { + rendering_program_p_l.enableAttributeArray("color"); + } + glPointSize(m_size_points); + glDrawArrays(GL_POINTS, 0, static_cast(arrays[POS_COLORED_POINTS].size()/3)); + vao[VAO_COLORED_POINTS].release(); + + rendering_program_p_l.release(); + } + + if(m_draw_edges) + { + rendering_program_p_l.bind(); + + vao[VAO_MONO_SEGMENTS].bind(); + color.setRgbF((double)m_edges_mono_color.red()/(double)255, + (double)m_edges_mono_color.green()/(double)255, + (double)m_edges_mono_color.blue()/(double)255); + rendering_program_p_l.setAttributeValue("color",color); + glLineWidth(m_size_edges); + glDrawArrays(GL_LINES, 0, static_cast(arrays[POS_MONO_SEGMENTS].size()/3)); + vao[VAO_MONO_SEGMENTS].release(); + + vao[VAO_COLORED_SEGMENTS].bind(); + if (m_use_mono_color) + { + color.setRgbF((double)m_edges_mono_color.red()/(double)255, + (double)m_edges_mono_color.green()/(double)255, + (double)m_edges_mono_color.blue()/(double)255); + rendering_program_p_l.disableAttributeArray("color"); + rendering_program_p_l.setAttributeValue("color",color); + } + else + { + rendering_program_p_l.enableAttributeArray("color"); + } + glLineWidth(m_size_edges); + glDrawArrays(GL_LINES, 0, static_cast(arrays[POS_COLORED_SEGMENTS].size()/3)); + vao[VAO_COLORED_SEGMENTS].release(); + + rendering_program_p_l.release(); + } + + if (m_draw_faces) + { + rendering_program_face.bind(); + + vao[VAO_MONO_FACES].bind(); + color.setRgbF((double)m_faces_mono_color.red()/(double)255, + (double)m_faces_mono_color.green()/(double)255, + (double)m_faces_mono_color.blue()/(double)255); + rendering_program_face.setAttributeValue("color",color); + glDrawArrays(GL_TRIANGLES, 0, static_cast(arrays[POS_MONO_FACES].size()/3)); + vao[VAO_MONO_FACES].release(); + + vao[VAO_COLORED_FACES].bind(); + if (m_use_mono_color) + { + color.setRgbF((double)m_faces_mono_color.red()/(double)255, + (double)m_faces_mono_color.green()/(double)255, + (double)m_faces_mono_color.blue()/(double)255); + rendering_program_face.disableAttributeArray("color"); + rendering_program_face.setAttributeValue("color",color); + } + else + { + rendering_program_face.enableAttributeArray("color"); + } + glDrawArrays(GL_TRIANGLES, 0, static_cast(arrays[POS_COLORED_FACES].size()/3)); + vao[VAO_COLORED_FACES].release(); + + rendering_program_face.release(); + } + } + + virtual void redraw() + { + initialize_buffers(); + update(); + } + + virtual void init() + { + // Restore previous viewer state. + restoreStateFromFile(); + initializeOpenGLFunctions(); + + // Define 'Control+Q' as the new exit shortcut (default was 'Escape') + setShortcut(qglviewer::EXIT_VIEWER, ::Qt::CTRL+::Qt::Key_Q); + + // Add custom key description (see keyPressEvent). + setKeyDescription(::Qt::Key_E, "Toggles edges display"); + setKeyDescription(::Qt::Key_F, "Toggles faces display"); + setKeyDescription(::Qt::Key_G, "Switch between flat/Gouraud shading display"); + setKeyDescription(::Qt::Key_M, "Toggles mono color for all faces"); + setKeyDescription(::Qt::Key_N, "Inverse direction of normals"); + setKeyDescription(::Qt::Key_V, "Toggles vertices display"); + setKeyDescription(::Qt::Key_Plus, "Increase size of edges"); + setKeyDescription(::Qt::Key_Minus, "Decrease size of edges"); + setKeyDescription(::Qt::Key_Plus+::Qt::ControlModifier, "Increase size of vertices"); + setKeyDescription(::Qt::Key_Minus+::Qt::ControlModifier, "Decrease size of vertices"); + setKeyDescription(::Qt::Key_PageDown, "Increase light (all colors, use shift/alt/ctrl for one rgb component)"); + setKeyDescription(::Qt::Key_PageUp, "Decrease light (all colors, use shift/alt/ctrl for one rgb component)"); + + // Light default parameters + glLineWidth(m_size_edges); + glPointSize(m_size_points); + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(1.f,1.f); + glClearColor(1.0f,1.0f,1.0f,0.0f); + glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + glEnable(GL_LIGHTING); + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); + glShadeModel(GL_FLAT); + glDisable(GL_BLEND); + glEnable(GL_LINE_SMOOTH); + glDisable(GL_POLYGON_SMOOTH_HINT); + glBlendFunc(GL_ONE, GL_ZERO); + glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST); + + compile_shaders(); + + CGAL::Bbox_3 bb; + if (bb==bounding_box()) // Case of "empty" bounding box + { + bb=Local_point(CGAL::ORIGIN).bbox(); + bb=bb + Local_point(1,1,1).bbox(); // To avoid a warning from Qglviewer + } + else + { bb=bounding_box(); } + this->camera()->setSceneBoundingBox(CGAL::qglviewer::Vec(bb.xmin(), + bb.ymin(), + bb.zmin()), + CGAL::qglviewer::Vec(bb.xmax(), + bb.ymax(), + bb.zmax())); + + this->showEntireScene(); + } + + void negate_all_normals() + { + for (unsigned int k=BEGIN_NORMAL; kmodifiers(); + + if ((e->key()==::Qt::Key_E) && (modifiers==::Qt::NoButton)) + { + m_draw_edges=!m_draw_edges; + displayMessage(QString("Draw edges=%1.").arg(m_draw_edges?"true":"false")); + update(); + } + else if ((e->key()==::Qt::Key_F) && (modifiers==::Qt::NoButton)) + { + m_draw_faces=!m_draw_faces; + displayMessage(QString("Draw faces=%1.").arg(m_draw_faces?"true":"false")); + update(); + } + else if ((e->key()==::Qt::Key_G) && (modifiers==::Qt::NoButton)) + { + m_flatShading=!m_flatShading; + if (m_flatShading) + displayMessage("Flat shading."); + else + displayMessage("Gouraud shading."); + redraw(); + } + else if ((e->key()==::Qt::Key_M) && (modifiers==::Qt::NoButton)) + { + m_use_mono_color=!m_use_mono_color; + displayMessage(QString("Mono color=%1.").arg(m_use_mono_color?"true":"false")); + update(); + } + else if ((e->key()==::Qt::Key_N) && (modifiers==::Qt::NoButton)) + { + m_inverse_normal=!m_inverse_normal; + displayMessage(QString("Inverse normal=%1.").arg(m_inverse_normal?"true":"false")); + negate_all_normals(); + redraw(); + } + else if ((e->key()==::Qt::Key_V) && (modifiers==::Qt::NoButton)) + { + m_draw_vertices=!m_draw_vertices; + displayMessage(QString("Draw vertices=%1.").arg(m_draw_vertices?"true":"false")); + update(); + } + else if ((e->key()==::Qt::Key_Plus) && (!modifiers.testFlag(::Qt::ControlModifier))) // No ctrl + { + m_size_edges+=.5; + displayMessage(QString("Size of edges=%1.").arg(m_size_edges)); + update(); + } + else if ((e->key()==::Qt::Key_Minus) && (!modifiers.testFlag(::Qt::ControlModifier))) // No ctrl + { + if (m_size_edges>.5) m_size_edges-=.5; + displayMessage(QString("Size of edges=%1.").arg(m_size_edges)); + update(); + } + else if ((e->key()==::Qt::Key_Plus) && (modifiers.testFlag(::Qt::ControlModifier))) + { + m_size_points+=.5; + displayMessage(QString("Size of points=%1.").arg(m_size_points)); + update(); + } + else if ((e->key()==::Qt::Key_Minus) && (modifiers.testFlag(::Qt::ControlModifier))) + { + if (m_size_points>.5) m_size_points-=.5; + displayMessage(QString("Size of points=%1.").arg(m_size_points)); + update(); + } + else if ((e->key()==::Qt::Key_PageUp) && (modifiers==::Qt::NoButton)) + { + m_ambient_color.setX(m_ambient_color.x()+.1); + if (m_ambient_color.x()>1.) m_ambient_color.setX(1.); + m_ambient_color.setY(m_ambient_color.x()+.1); + if (m_ambient_color.y()>1.) m_ambient_color.setY(1.); + m_ambient_color.setZ(m_ambient_color.x()+.1); + if (m_ambient_color.z()>1.) m_ambient_color.setZ(1.); + displayMessage(QString("Light color=(%1 %2 %3)."). + arg(m_ambient_color.x()).arg(m_ambient_color.y()).arg(m_ambient_color.z())); + update(); + } + else if ((e->key()==::Qt::Key_PageDown) && (modifiers==::Qt::NoButton)) + { + m_ambient_color.setX(m_ambient_color.x()-.1); + if (m_ambient_color.x()<0.) m_ambient_color.setX(0.); + m_ambient_color.setY(m_ambient_color.y()-.1); + if (m_ambient_color.y()<0.) m_ambient_color.setY(0.); + m_ambient_color.setZ(m_ambient_color.z()-.1); + if (m_ambient_color.z()<0.) m_ambient_color.setZ(0.); + displayMessage(QString("Light color=(%1 %2 %3)."). + arg(m_ambient_color.x()).arg(m_ambient_color.y()).arg(m_ambient_color.z())); + update(); + } + else if ((e->key()==::Qt::Key_PageUp) && (modifiers==::Qt::ShiftModifier)) + { + m_ambient_color.setX(m_ambient_color.x()+.1); + if (m_ambient_color.x()>1.) m_ambient_color.setX(1.); + displayMessage(QString("Light color=(%1 %2 %3)."). + arg(m_ambient_color.x()).arg(m_ambient_color.y()).arg(m_ambient_color.z())); + update(); + } + else if ((e->key()==::Qt::Key_PageUp) && (modifiers==::Qt::AltModifier)) + { + m_ambient_color.setY(m_ambient_color.y()+.1); + if (m_ambient_color.y()>1.) m_ambient_color.setY(1.); + displayMessage(QString("Light color=(%1 %2 %3)."). + arg(m_ambient_color.x()).arg(m_ambient_color.y()).arg(m_ambient_color.z())); + update(); + } + else if ((e->key()==::Qt::Key_PageUp) && (modifiers==::Qt::ControlModifier)) + { + m_ambient_color.setZ(m_ambient_color.z()+.1); + if (m_ambient_color.z()>1.) m_ambient_color.setZ(1.); + displayMessage(QString("Light color=(%1 %2 %3)."). + arg(m_ambient_color.x()).arg(m_ambient_color.y()).arg(m_ambient_color.z())); + update(); + } + else if ((e->key()==::Qt::Key_PageDown) && (modifiers==::Qt::ShiftModifier)) + { + m_ambient_color.setX(m_ambient_color.x()-.1); + if (m_ambient_color.x()<0.) m_ambient_color.setX(0.); + displayMessage(QString("Light color=(%1 %2 %3)."). + arg(m_ambient_color.x()).arg(m_ambient_color.y()).arg(m_ambient_color.z())); + update(); + } + else if ((e->key()==::Qt::Key_PageDown) && (modifiers==::Qt::AltModifier)) + { + m_ambient_color.setY(m_ambient_color.y()-.1); + if (m_ambient_color.y()<0.) m_ambient_color.setY(0.); + displayMessage(QString("Light color=(%1 %2 %3)."). + arg(m_ambient_color.x()).arg(m_ambient_color.y()).arg(m_ambient_color.z())); + update(); + } + else if ((e->key()==::Qt::Key_PageDown) && (modifiers==::Qt::ControlModifier)) + { + m_ambient_color.setZ(m_ambient_color.z()-.1); + if (m_ambient_color.z()<0.) m_ambient_color.setZ(0.); + displayMessage(QString("Light color=(%1 %2 %3)."). + arg(m_ambient_color.x()).arg(m_ambient_color.y()).arg(m_ambient_color.z())); + update(); + } + else + CGAL::QGLViewer::keyPressEvent(e); + } + + virtual QString helpString() const + { + QString text("

C G A L B a s i c V i e w e r

"); + text += "Use the mouse to move the camera around the object. "; + text += "You can respectively revolve around, zoom and translate with " + "the three mouse buttons. "; + text += "Left and middle buttons pressed together rotate around the " + "camera view direction axis

"; + text += "Pressing Alt and one of the function keys " + "(F1..F12) defines a camera keyFrame. "; + text += "Simply press the function key again to restore it. " + "Several keyFrames define a "; + text += "camera path. Paths are saved when you quit the application " + "and restored at next start.

"; + text += "Press F to display the frame rate, A for the " + "world axis, "; + text += "Alt+Return for full screen mode and Control+S " + "to save a snapshot. "; + text += "See the Keyboard tab in this window for a complete " + "shortcut list.

"; + text += "Double clicks automates single click actions: A left button " + "double click aligns the closer axis with the camera (if close enough). "; + text += "A middle button double click fits the zoom of the camera and " + "the right button re-centers the scene.

"; + text += "A left button double click while holding right button pressed " + "defines the camera Revolve Around Point. "; + text += "See the Mouse tab and the documentation web pages for " + "details.

"; + text += "Press Escape to exit the viewer."; + return text; + } + +private: + bool m_draw_vertices; + bool m_draw_edges; + bool m_draw_faces; + bool m_flatShading; + bool m_use_mono_color; + bool m_inverse_normal; + + double m_size_points; + double m_size_edges; + + CGAL::Color m_vertices_mono_color; + CGAL::Color m_edges_mono_color; + CGAL::Color m_faces_mono_color; + QVector4D m_ambient_color; + + bool m_are_buffers_initialized; + CGAL::Bbox_3 m_bounding_box; + + // The following enum gives the indices of different elements of arrays vectors. + enum + { + BEGIN_POS=0, + POS_MONO_POINTS=BEGIN_POS, + POS_COLORED_POINTS, + POS_MONO_SEGMENTS, + POS_COLORED_SEGMENTS, + POS_MONO_FACES, + POS_COLORED_FACES, + END_POS, + BEGIN_COLOR=END_POS, + COLOR_POINTS=BEGIN_COLOR, + COLOR_SEGMENTS, + COLOR_FACES, + END_COLOR, + BEGIN_NORMAL=END_COLOR, + SMOOTH_NORMAL_MONO_FACES=BEGIN_NORMAL, + FLAT_NORMAL_MONO_FACES, + SMOOTH_NORMAL_COLORED_FACES, + FLAT_NORMAL_COLORED_FACES, + END_NORMAL, + LAST_INDEX=END_NORMAL + }; + std::vector arrays[LAST_INDEX]; + + Buffer_for_vao m_buffer_for_mono_points; + Buffer_for_vao m_buffer_for_colored_points; + Buffer_for_vao m_buffer_for_mono_segments; + Buffer_for_vao m_buffer_for_colored_segments; + Buffer_for_vao m_buffer_for_mono_faces; + Buffer_for_vao m_buffer_for_colored_faces; + + static const unsigned int NB_VBO_BUFFERS=(END_POS-BEGIN_POS)+ + (END_COLOR-BEGIN_COLOR)+2; // +2 for 2 vectors of normals + + QGLBuffer buffers[NB_VBO_BUFFERS]; + + // The following enum gives the indices of the differents vao. + enum + { VAO_MONO_POINTS=0, + VAO_COLORED_POINTS, + VAO_MONO_SEGMENTS, + VAO_COLORED_SEGMENTS, + VAO_MONO_FACES, + VAO_COLORED_FACES, + NB_VAO_BUFFERS + }; + QOpenGLVertexArrayObject vao[NB_VAO_BUFFERS]; + + QOpenGLShaderProgram rendering_program_face; + QOpenGLShaderProgram rendering_program_p_l; +}; + +} // End namespace CGAL + +#else // CGAL_USE_BASIC_VIEWER + +namespace CGAL +{ + +template +void draw(const T&, const char*, bool, const ColorFunctor&) +{ + std::cerr<<"Impossible to draw because CGAL_USE_BASIC_VIEWER is not defined." + < +void draw(const T&, const char*, bool) +{ + std::cerr<<"Impossible to draw because CGAL_USE_BASIC_VIEWER is not defined." + < +void draw(const T&, const char*) +{ + std::cerr<<"Impossible to draw because CGAL_USE_BASIC_VIEWER is not defined." + < +void draw(const T&) +{ + std::cerr<<"Impossible to draw because CGAL_USE_BASIC_VIEWER is not defined." + < - class Draw : public CGAL::iterator { + class Draw + : public CGAL::cpp98::iterator { QPainter* painter; QMatrix* matrix; Converter convert; diff --git a/GraphicsView/include/CGAL/Qt/camera.h b/GraphicsView/include/CGAL/Qt/camera.h new file mode 100644 index 00000000000..88f355fe9e4 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/camera.h @@ -0,0 +1,539 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 + + +#ifndef QGLVIEWER_CAMERA_H +#define QGLVIEWER_CAMERA_H +#include +#include +#include +#include +#include +#include + +namespace CGAL{ +class QGLViewer; +namespace qglviewer { + +class KeyFrameInterpolator; +class Frame; +class ManipulatedCameraFrame; + + +/*! \brief A perspective or orthographic camera. + \class Camera camera.h CGAL::QGLViewer/camera.h + + A Camera defines some intrinsic parameters (fieldOfView(), position(), + viewDirection(), upVector()...) and useful positioning tools that ease its + placement (showEntireScene(), fitSphere(), lookAt()...). It exports its + associated OpenGL projection and modelview matrices and can interactively be + modified using the mouse. + +

Mouse manipulation

+ + The position() and orientation() of the Camera are defined by a + ManipulatedCameraFrame (retrieved using frame()). These methods are just + convenient wrappers to the equivalent Frame methods. This also means that the + Camera frame() can be attached to a Frame::referenceFrame() which enables + complex Camera setups. + + Different displacements can be performed using the mouse. The list of possible + actions is defined by the CGAL::QGLViewer::MouseAction enum. Use + CGAL::QGLViewer::setMouseBinding() to attach a specific action to an arbitrary mouse + button-state key binding. These actions are detailed in the mouse page. + + The default button binding are: CGAL::QGLViewer::ROTATE (left), CGAL::QGLViewer::ZOOM + (middle) and CGAL::QGLViewer::TRANSLATE (right). With this configuration, the Camera + \e observes a scene and rotates around its pivotPoint(). You can switch + between this mode and a fly mode using the CGAL::QGLViewer::CAMERA_MODE (see + CGAL::QGLViewer::toggleCameraMode()) keyboard shortcut (default is 'Space'). + +

Other functionalities

+ + The type() of the Camera can be Camera::ORTHOGRAPHIC or Camera::PERSPECTIVE + (see Type()). fieldOfView() is meaningless with Camera::ORTHOGRAPHIC. + + The near and far planes of the Camera are fitted to the scene and determined + from CGAL::QGLViewer::sceneRadius(), CGAL::QGLViewer::sceneCenter() and + zClippingCoefficient() by the zNear() and zFar() methods. Reasonable values on + the scene extends hence have to be provided to the CGAL::QGLViewer in order for the + Camera to correctly display the scene. High level positioning methods also use + this information (showEntireScene(), centerScene()...). + + A Camera holds KeyFrameInterpolator that can be used to save Camera positions + and paths. You can interactively addKeyFrameToPath() to a given path using the + default \c Alt+F[1-12] shortcuts. Use playPath() to make the Camera follow the + path (default shortcut is F[1-12]). See the keyboard page for details on key customization. + + Use cameraCoordinatesOf() and worldCoordinatesOf() to convert to and from the + Camera frame() coordinate system. projectedCoordinatesOf() and + unprojectedCoordinatesOf() will convert from screen to 3D coordinates. + convertClickToLine() is very useful for analytical object selection. + + Stereo display is possible on machines with quad buffer capabilities (with + Camera::PERSPECTIVE type() only). Test the stereoViewer example to check. + + A Camera can also be used outside of a CGAL::QGLViewer or even without OpenGL for + its coordinate system conversion capabilities. Note however that some of them + explicitly rely on the presence of a Z-buffer. \nosubgrouping */ +class CGAL_QT_EXPORT Camera : public QObject { +#ifndef DOXYGEN + friend class ::CGAL::QGLViewer; +#endif + + Q_OBJECT + +public: + Camera(QObject *parent); + virtual ~Camera(); + + Camera(const Camera &camera); + Camera &operator=(const Camera &camera); + + /*! Enumerates the two possible types of Camera. + + See type() and setType(). This type mainly defines different Camera projection + matrix (see loadProjectionMatrix()). Many other methods (pointUnderPixel(), + convertClickToLine(), projectedCoordinatesOf(), pixelGLRatio()...) are + affected by this Type. */ + enum Type { PERSPECTIVE, ORTHOGRAPHIC }; + + /*! @name Position and orientation */ + //@{ +public: + Vec position() const; + Vec upVector() const; + Vec viewDirection() const; + Vec rightVector() const; + Quaternion orientation() const; + + void setFromModelViewMatrix(const GLdouble *const modelViewMatrix); + void setFromProjectionMatrix(const qreal matrix[12]); + +public Q_SLOTS: + void setPosition(const Vec &pos); + void setOrientation(const Quaternion &q); + void setOrientation(qreal theta, qreal phi); + void setUpVector(const Vec &up, bool noMove = true); + void setViewDirection(const Vec &direction); + //@} + + /*! @name Positioning tools */ + //@{ +public Q_SLOTS: + void lookAt(const Vec &target); + void showEntireScene(); + void fitSphere(const Vec ¢er, qreal radius); + void fitBoundingBox(const Vec &min, const Vec &max); + void fitScreenRegion(const QRect &rectangle); + void centerScene(); + void interpolateToZoomOnPixel(const QPoint &pixel); + void interpolateToFitScene(); + void interpolateTo(const Frame &fr, qreal duration); + //@} + + /*! @name Frustum */ + //@{ +public: + /*! Returns the Camera::Type of the Camera. + + Set by setType(). Mainly used by loadProjectionMatrix(). + + A Camera::PERSPECTIVE Camera uses a classical projection mainly defined by its + fieldOfView(). + + With a Camera::ORTHOGRAPHIC type(), the fieldOfView() is meaningless and the + width and height of the Camera frustum are inferred from the distance to the + pivotPoint() using getOrthoWidthHeight(). + + Both types use zNear() and zFar() (to define their clipping planes) and + aspectRatio() (for frustum shape). */ + Type type() const { return type_; } + + /*! Returns the vertical field of view of the Camera (in radians). + + Value is set using setFieldOfView(). Default value is pi/4 radians. This value + is meaningless if the Camera type() is Camera::ORTHOGRAPHIC. + + The field of view corresponds the one used in \c gluPerspective (see manual). + It sets the Y (vertical) aperture of the Camera. The X (horizontal) angle is + inferred from the window aspect ratio (see aspectRatio() and + horizontalFieldOfView()). + + Use setFOVToFitScene() to adapt the fieldOfView() to a given scene. */ + qreal fieldOfView() const { return fieldOfView_; } + + /*! Returns the horizontal field of view of the Camera (in radians). + + Value is set using setHorizontalFieldOfView() or setFieldOfView(). These + values are always linked by: \code horizontalFieldOfView() = 2.0 * atan ( + tan(fieldOfView()/2.0) * aspectRatio() ). \endcode */ + qreal horizontalFieldOfView() const; + + /*! Returns the Camera aspect ratio defined by screenWidth() / screenHeight(). + + When the Camera is attached to a CGAL::QGLViewer, these values and hence the + aspectRatio() are automatically fitted to the viewer's window aspect ratio + using setScreenWidthAndHeight(). */ + qreal aspectRatio() const { + return screenWidth_ / static_cast(screenHeight_); + } + /*! Returns the width (in pixels) of the Camera screen. + + Set using setScreenWidthAndHeight(). This value is automatically fitted to the + CGAL::QGLViewer's window dimensions when the Camera is attached to a CGAL::QGLViewer. See + also QOpenGLWidget::width() */ + int screenWidth() const { return screenWidth_; } + /*! Returns the height (in pixels) of the Camera screen. + + Set using setScreenWidthAndHeight(). This value is automatically fitted to the + CGAL::QGLViewer's window dimensions when the Camera is attached to a CGAL::QGLViewer. See + also QOpenGLWidget::height() */ + int screenHeight() const { return screenHeight_; } + void getViewport(GLint viewport[4]) const; + qreal pixelGLRatio(const Vec &position) const; + + /*! Returns the coefficient which is used to set zNear() when the Camera is + inside the sphere defined by sceneCenter() and zClippingCoefficient() * + sceneRadius(). + + In that case, the zNear() value is set to zNearCoefficient() * + zClippingCoefficient() * sceneRadius(). See the zNear() documentation for + details. + + Default value is 0.005, which is appropriate for most applications. In case + you need a high dynamic ZBuffer precision, you can increase this value (~0.1). + A lower value will prevent clipping of very close objects at the expense of a + worst Z precision. + + Only meaningful when Camera type is Camera::PERSPECTIVE. */ + qreal zNearCoefficient() const { return zNearCoef_; } + /*! Returns the coefficient used to position the near and far clipping planes. + + The near (resp. far) clipping plane is positioned at a distance equal to + zClippingCoefficient() * sceneRadius() in front of (resp. behind) the + sceneCenter(). This garantees an optimal use of the z-buffer range and + minimizes aliasing. See the zNear() and zFar() documentations. + + Default value is square root of 3.0 (so that a cube of size sceneRadius() is + not clipped). + + However, since the sceneRadius() is used for other purposes (see + showEntireScene(), flySpeed(), + ...) and you may want to change this value to define more precisely the + location of the clipping planes. See also zNearCoefficient(). + + For a total control on clipping planes' positions, an other option is to + overload the zNear() and zFar() methods. See the standardCamera example. + + \attention When CGAL::QGLViewer::cameraPathAreEdited(), this value is set to 5.0 so + that the Camera paths are not clipped. The previous zClippingCoefficient() + value is restored back when you leave this mode. */ + qreal zClippingCoefficient() const { return zClippingCoef_; } + + virtual qreal zNear() const; + virtual qreal zFar() const; + virtual void getOrthoWidthHeight(GLdouble &halfWidth, + GLdouble &halfHeight) const; + void getFrustumPlanesCoefficients(GLdouble coef[6][4]) const; + +public Q_SLOTS: + void setType(Type type); + + void setFieldOfView(qreal fov); + + /*! Sets the horizontalFieldOfView() of the Camera (in radians). + + horizontalFieldOfView() and fieldOfView() are linked by the aspectRatio(). + This method actually calls setFieldOfView(( 2.0 * atan (tan(hfov / 2.0) / + aspectRatio()) )) so that a call to horizontalFieldOfView() returns the + expected value. */ + void setHorizontalFieldOfView(qreal hfov); + + void setFOVToFitScene(); + + /*! Defines the Camera aspectRatio(). + + This value is actually inferred from the screenWidth() / screenHeight() ratio. + You should use setScreenWidthAndHeight() instead. + + This method might however be convenient when the Camera is not associated with + a CGAL::QGLViewer. It actually sets the screenHeight() to 100 and the screenWidth() + accordingly. See also setFOVToFitScene(). + + \note If you absolutely need an aspectRatio() that does not correspond to your + viewer's window dimensions, overload loadProjectionMatrix() or multiply the + created GL_PROJECTION matrix by a scaled diagonal matrix in your + CGAL::QGLViewer::draw() method. */ + void setAspectRatio(qreal aspect) { + setScreenWidthAndHeight(int(100.0 * aspect), 100); + } + + void setScreenWidthAndHeight(int width, int height); + /*! Sets the zNearCoefficient() value. */ + void setZNearCoefficient(qreal coef) { + zNearCoef_ = coef; + projectionMatrixIsUpToDate_ = false; + } + /*! Sets the zClippingCoefficient() value. */ + void setZClippingCoefficient(qreal coef) { + zClippingCoef_ = coef; + projectionMatrixIsUpToDate_ = false; + } + //@} + + /*! @name Scene radius and center */ + //@{ +public: + /*! Returns the radius of the scene observed by the Camera. + + You need to provide such an approximation of the scene dimensions so that the + Camera can adapt its zNear() and zFar() values. See the sceneCenter() + documentation. + + See also setSceneBoundingBox(). + + Note that CGAL::QGLViewer::sceneRadius() (resp. CGAL::QGLViewer::setSceneRadius()) simply + call this method (resp. setSceneRadius()) on its associated + CGAL::QGLViewer::camera(). */ + qreal sceneRadius() const { return sceneRadius_; } + + /*! Returns the position of the scene center, defined in the world coordinate + system. + + The scene observed by the Camera should be roughly centered on this position, + and included in a sceneRadius() sphere. This approximate description of the + scene permits a zNear() and zFar() clipping planes definition, and allows + convenient positioning methods such as showEntireScene(). + + Default value is (0,0,0) (world origin). Use setSceneCenter() to change it. + See also setSceneBoundingBox(). + + Note that CGAL::QGLViewer::sceneCenter() (resp. CGAL::QGLViewer::setSceneCenter()) simply + calls this method (resp. setSceneCenter()) on its associated + CGAL::QGLViewer::camera(). */ + Vec sceneCenter() const { return sceneCenter_; } + qreal distanceToSceneCenter() const; + +public Q_SLOTS: + void setSceneRadius(qreal radius); + void setSceneCenter(const Vec ¢er); + bool setSceneCenterFromPixel(const QPoint &pixel); + void setSceneBoundingBox(const Vec &min, const Vec &max); + //@} + + /*! @name Pivot Point */ + //@{ +public Q_SLOTS: + void setPivotPoint(const Vec &point); + bool setPivotPointFromPixel(const QPoint &pixel); + +public: + Vec pivotPoint() const; + + //@} + + /*! @name Associated frame */ + //@{ +public: + /*! Returns the ManipulatedCameraFrame attached to the Camera. + + This ManipulatedCameraFrame defines its position() and orientation() and can + translate mouse events into Camera displacement. Set using setFrame(). */ + ManipulatedCameraFrame *frame() const { return frame_; } +public Q_SLOTS: + void setFrame(ManipulatedCameraFrame *const mcf); + //@} + + /*! @name KeyFramed paths */ + //@{ +public: + KeyFrameInterpolator *keyFrameInterpolator(unsigned int i) const; + +public Q_SLOTS: + void setKeyFrameInterpolator(unsigned int i, KeyFrameInterpolator *const kfi); + + virtual void addKeyFrameToPath(unsigned int i); + virtual void playPath(unsigned int i); + virtual void deletePath(unsigned int i); + virtual void resetPath(unsigned int i); + //@} + + /*! @name OpenGL matrices */ + //@{ +public: + virtual void loadProjectionMatrix(bool reset = true) const; + virtual void loadModelViewMatrix(bool reset = true) const; + void computeProjectionMatrix() const; + void computeModelViewMatrix() const; + //!Sets the frustum according to the current type of the camera + //! (PERSPECTIVE or ORTHOGRAPHIC) in this order : + //! left, right, top, bottom, near, far + void setFrustum(double frustum[6]); + //!Fills `frustum` from the current frustum of the camera according + //! to the current type (PERSPECTIVE or ORTHOGRAPHIC) in this order : + //! left, right, top, bottom, near, far + void getFrustum(double frustum[6]); + + virtual void loadProjectionMatrixStereo(bool leftBuffer = true) const; + virtual void loadModelViewMatrixStereo(bool leftBuffer = true) const; + + void getProjectionMatrix(GLfloat m[16]) const; + void getProjectionMatrix(GLdouble m[16]) const; + + void getModelViewMatrix(GLfloat m[16]) const; + void getModelViewMatrix(GLdouble m[16]) const; + + void getModelViewProjectionMatrix(GLfloat m[16]) const; + void getModelViewProjectionMatrix(GLdouble m[16]) const; +//@} + + /*! @name World to Camera coordinate systems conversions */ + //@{ +public: + Vec cameraCoordinatesOf(const Vec &src) const; + Vec worldCoordinatesOf(const Vec &src) const; + void getCameraCoordinatesOf(const qreal src[3], qreal res[3]) const; + void getWorldCoordinatesOf(const qreal src[3], qreal res[3]) const; + //@} + + /*! @name 2D screen to 3D world coordinate systems conversions */ + //@{ +public: + Vec projectedCoordinatesOf(const Vec &src, const Frame *frame = NULL) const; + Vec unprojectedCoordinatesOf(const Vec &src, const Frame *frame = NULL) const; + void getProjectedCoordinatesOf(const qreal src[3], qreal res[3], + const Frame *frame = NULL) const; + void getUnprojectedCoordinatesOf(const qreal src[3], qreal res[3], + const Frame *frame = NULL) const; + void convertClickToLine(const QPoint &pixel, Vec &orig, Vec &dir) const; + Vec pointUnderPixel(const QPoint &pixel, bool &found) const; + //@} + + /*! @name Fly speed */ + //@{ +public: + qreal flySpeed() const; +public Q_SLOTS: + void setFlySpeed(qreal speed); + //@} + + /*! @name Stereo parameters */ + //@{ +public: + /*! Returns the user's inter-ocular distance (in meters). Default value is + 0.062m, which fits most people. + + loadProjectionMatrixStereo() uses this value to define the Camera offset and + frustum. See setIODistance(). */ + qreal IODistance() const { return IODistance_; } + + /*! Returns the physical distance between the user's eyes and the screen (in + meters). + + physicalDistanceToScreen() and focusDistance() represent the same distance. + The former is expressed in physical real world units, while the latter is + expressed in OpenGL virtual world units. + + This is a helper function. It simply returns physicalScreenWidth() / 2.0 / + tan(horizontalFieldOfView() / 2.0); */ + qreal physicalDistanceToScreen() const; + + /*! Returns the physical screen width, in meters. Default value is 0.5m + (average monitor width). + + Used for stereo display only (see loadModelViewMatrixStereo() and + loadProjectionMatrixStereo()). Set using setPhysicalScreenWidth(). */ + qreal physicalScreenWidth() const { return physicalScreenWidth_; } + + /*! Returns the focus distance used by stereo display, expressed in OpenGL + units. + + This is the distance in the virtual world between the Camera and the plane + where the horizontal stereo parallax is null (the stereo left and right + cameras' lines of sigth cross at this distance). + + This distance is the virtual world equivalent of the real-world + physicalDistanceToScreen(). + + \attention This value is modified by CGAL::QGLViewer::setSceneRadius(), + setSceneRadius() and setFieldOfView(). When one of these values is modified, + focusDistance() is set to sceneRadius() / tan(fieldOfView()/2), which provides + good results. */ + qreal focusDistance() const { return focusDistance_; } +public Q_SLOTS: + /*! Sets the IODistance(). */ + void setIODistance(qreal distance) { IODistance_ = distance; } + + /*! Sets the physical screen (monitor or projected wall) width (in meters). */ + void setPhysicalScreenWidth(qreal width) { physicalScreenWidth_ = width; } + + /*! Sets the focusDistance(), in OpenGL scene units. */ + void setFocusDistance(qreal distance) { focusDistance_ = distance; } + //@} + + /*! @name XML representation */ + //@{ +public: + virtual QDomElement domElement(const QString &name, + QDomDocument &document) const; +public Q_SLOTS: + virtual void initFromDOMElement(const QDomElement &element); + //@} + +private Q_SLOTS: + void onFrameModified(); + +private: + QOpenGLFunctions_2_1* gl() const{ return dynamic_cast(parent()); } + // F r a m e + ManipulatedCameraFrame *frame_; + + // C a m e r a p a r a m e t e r s + int screenWidth_, screenHeight_; // size of the window, in pixels + qreal fieldOfView_; // in radians + Vec sceneCenter_; + qreal sceneRadius_; // OpenGL units + qreal zNearCoef_; + qreal zClippingCoef_; + qreal orthoCoef_; + Type type_; // PERSPECTIVE or ORTHOGRAPHIC + mutable GLdouble modelViewMatrix_[16]; // Buffered model view matrix. + mutable bool modelViewMatrixIsUpToDate_; + mutable GLdouble projectionMatrix_[16]; // Buffered projection matrix. + mutable bool projectionMatrixIsUpToDate_; + + // S t e r e o p a r a m e t e r s + qreal IODistance_; // inter-ocular distance, in meters + qreal focusDistance_; // in scene units + qreal physicalScreenWidth_; // in meters + + // P o i n t s o f V i e w s a n d K e y F r a m e s + QMap kfi_; + KeyFrameInterpolator *interpolationKfi_; +}; + +} // namespace qglviewer +} //CGAL +#endif // QGLVIEWER_CAMERA_H diff --git a/GraphicsView/include/CGAL/Qt/camera_impl.h b/GraphicsView/include/CGAL/Qt/camera_impl.h new file mode 100644 index 00000000000..a0fee4d8d0c --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/camera_impl.h @@ -0,0 +1,2536 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 + +#ifdef CGAL_HEADER_ONLY +#define CGAL_INLINE_FUNCTION inline + +#include + +#else +#define CGAL_INLINE_FUNCTION +#endif + +#include +#include +#include +#include + +namespace CGAL{ +namespace qglviewer{ + +/*! Default constructor. + + sceneCenter() is set to (0,0,0) and sceneRadius() is set to 1.0. type() is + Camera::PERSPECTIVE, with a \c M_PI/4 fieldOfView(). + + See IODistance(), physicalDistanceToScreen(), physicalScreenWidth() and + focusDistance() documentations for default stereo parameter values. */ +CGAL_INLINE_FUNCTION +Camera::Camera(QObject *parent) + : frame_(NULL), fieldOfView_(CGAL_PI / 4.0), modelViewMatrixIsUpToDate_(false), + projectionMatrixIsUpToDate_(false) { + setParent(parent); + // #CONNECTION# Camera copy constructor + interpolationKfi_ = new KeyFrameInterpolator; + // Requires the interpolationKfi_ + setFrame(new ManipulatedCameraFrame()); + + // #CONNECTION# All these default values identical in initFromDOMElement. + + // Requires fieldOfView() to define focusDistance() + setSceneRadius(1.0); + + // Initial value (only scaled after this) + orthoCoef_ = tan(fieldOfView() / 2.0); + + // Also defines the pivotPoint(), which changes orthoCoef_. Requires a + // frame(). + setSceneCenter(Vec(0.0, 0.0, 0.0)); + + // Requires fieldOfView() when called with ORTHOGRAPHIC. Attention to + // projectionMatrix_ below. + setType(PERSPECTIVE); + + // #CONNECTION# initFromDOMElement default values + setZNearCoefficient(0.005); + setZClippingCoefficient(sqrt(3.0)); + + // Dummy values + setScreenWidthAndHeight(600, 400); + + // Stereo parameters + setIODistance(0.062); + setPhysicalScreenWidth(0.5); + // focusDistance is set from setFieldOfView() + + // #CONNECTION# Camera copy constructor + for (unsigned short j = 0; j < 16; ++j) { + modelViewMatrix_[j] = ((j % 5 == 0) ? 1.0 : 0.0); + // #CONNECTION# computeProjectionMatrix() is lazy and assumes 0.0 almost + // everywhere. + projectionMatrix_[j] = 0.0; + } + computeProjectionMatrix(); +} + +/*! Virtual destructor. + + The frame() is deleted, but the different keyFrameInterpolator() are \e not + deleted (in case they are shared). */ + +CGAL_INLINE_FUNCTION +Camera::~Camera() { + delete frame_; + delete interpolationKfi_; +} + +/*! Copy constructor. Performs a deep copy using operator=(). */ +CGAL_INLINE_FUNCTION +Camera::Camera(const Camera &camera) : QObject(), frame_(NULL) { + // #CONNECTION# Camera constructor + interpolationKfi_ = new KeyFrameInterpolator; + // Requires the interpolationKfi_ + setFrame(new ManipulatedCameraFrame(*camera.frame())); + + for (unsigned short j = 0; j < 16; ++j) { + modelViewMatrix_[j] = ((j % 5 == 0) ? 1.0 : 0.0); + // #CONNECTION# computeProjectionMatrix() is lazy and assumes 0.0 almost + // everywhere. + projectionMatrix_[j] = 0.0; + } + + (*this) = camera; +} + +/*! Equal operator. + + All the parameters of \p camera are copied. The frame() pointer is not + modified, but its Frame::position() and Frame::orientation() are set to those + of \p camera. + + \attention The Camera screenWidth() and screenHeight() are set to those of \p + camera. If your Camera is associated with a CGAL::QGLViewer, you should update these + value after the call to this method: \code + *(camera()) = otherCamera; + camera()->setScreenWidthAndHeight(width(), height()); + \endcode + The same applies to sceneCenter() and sceneRadius(), if needed. */ +CGAL_INLINE_FUNCTION +Camera &Camera::operator=(const Camera &camera) { + setScreenWidthAndHeight(camera.screenWidth(), camera.screenHeight()); + setFieldOfView(camera.fieldOfView()); + setSceneRadius(camera.sceneRadius()); + setSceneCenter(camera.sceneCenter()); + setZNearCoefficient(camera.zNearCoefficient()); + setZClippingCoefficient(camera.zClippingCoefficient()); + setType(camera.type()); + + // Stereo parameters + setIODistance(camera.IODistance()); + setFocusDistance(camera.focusDistance()); + setPhysicalScreenWidth(camera.physicalScreenWidth()); + + orthoCoef_ = camera.orthoCoef_; + projectionMatrixIsUpToDate_ = false; + + // frame_ and interpolationKfi_ pointers are not shared. + frame_->setReferenceFrame(NULL); + frame_->setPosition(camera.position()); + frame_->setOrientation(camera.orientation()); + + interpolationKfi_->resetInterpolation(); + + kfi_ = camera.kfi_; + + computeProjectionMatrix(); + computeModelViewMatrix(); + + return *this; +} + +/*! Sets Camera screenWidth() and screenHeight() (expressed in pixels). + +You should not call this method when the Camera is associated with a CGAL::QGLViewer, +since the latter automatically updates these values when it is resized (hence +overwritting your values). + +Non-positive dimension are silently replaced by a 1 pixel value to ensure +frustrum coherence. + +If your Camera is used without a CGAL::QGLViewer (offscreen rendering, shadow maps), +use setAspectRatio() instead to define the projection matrix. */ +CGAL_INLINE_FUNCTION +void Camera::setScreenWidthAndHeight(int width, int height) { + // Prevent negative and zero dimensions that would cause divisions by zero. + screenWidth_ = width > 0 ? width : 1; + screenHeight_ = height > 0 ? height : 1; + projectionMatrixIsUpToDate_ = false; +} + +/*! Returns the near clipping plane distance used by the Camera projection + matrix. + + The clipping planes' positions depend on the sceneRadius() and sceneCenter() + rather than being fixed small-enough and large-enough values. A good scene + dimension approximation will hence result in an optimal precision of the + z-buffer. + + The near clipping plane is positioned at a distance equal to + zClippingCoefficient() * sceneRadius() in front of the sceneCenter(): \code + zNear = distanceToSceneCenter() - zClippingCoefficient()*sceneRadius(); + \endcode + + In order to prevent negative or too small zNear() values (which would degrade + the z precision), zNearCoefficient() is used when the Camera is inside the + sceneRadius() sphere: \code const qreal zMin = zNearCoefficient() * + zClippingCoefficient() * sceneRadius(); if (zNear < zMin) zNear = zMin; + // With an ORTHOGRAPHIC type, the value is simply clamped to 0.0 + \endcode + + See also the zFar(), zClippingCoefficient() and zNearCoefficient() + documentations. + + If you need a completely different zNear computation, overload the zNear() and + zFar() methods in a new class that publicly inherits from Camera and use + CGAL::QGLViewer::setCamera(): \code class myCamera :: public CGAL::qglviewer::Camera + { + virtual qreal Camera::zNear() const { return 0.001; }; + virtual qreal Camera::zFar() const { return 100.0; }; + } + \endcode + + See the standardCamera example + for an application. + + \attention The value is always positive although the clipping plane is + positioned at a negative z value in the Camera coordinate system. This follows + the \c gluPerspective standard. */ +CGAL_INLINE_FUNCTION +qreal Camera::zNear() const { + const qreal zNearScene = zClippingCoefficient() * sceneRadius(); + qreal z = distanceToSceneCenter() - zNearScene; + + // Prevents negative or null zNear values. + const qreal zMin = zNearCoefficient() * zNearScene; + if (z < zMin) + switch (type()) { + case Camera::PERSPECTIVE: + z = zMin; + break; + case Camera::ORTHOGRAPHIC: + z = 0.0; + break; + } + return z; +} + +/*! Returns the far clipping plane distance used by the Camera projection +matrix. + +The far clipping plane is positioned at a distance equal to +zClippingCoefficient() * sceneRadius() behind the sceneCenter(): \code zFar = +distanceToSceneCenter() + zClippingCoefficient()*sceneRadius(); \endcode + +See the zNear() documentation for details. */ +CGAL_INLINE_FUNCTION +qreal Camera::zFar() const { + return distanceToSceneCenter() + zClippingCoefficient() * sceneRadius(); +} + +/*! Sets the vertical fieldOfView() of the Camera (in radians). + +Note that focusDistance() is set to sceneRadius() / tan(fieldOfView()/2) by this +method. */ +CGAL_INLINE_FUNCTION +void Camera::setFieldOfView(qreal fov) { + fieldOfView_ = fov; + setFocusDistance(sceneRadius() / tan(fov / 2.0)); + projectionMatrixIsUpToDate_ = false; +} + +/*! Defines the Camera type(). + +Changing the camera Type alters the viewport and the objects' sizes can be +changed. This method garantees that the two frustum match in a plane normal to +viewDirection(), passing through the pivotPoint(). + +Prefix the type with \c Camera if needed, as in: +\code +camera()->setType(Camera::ORTHOGRAPHIC); +// or even CGAL::qglviewer::Camera::ORTHOGRAPHIC if you do not use namespace +\endcode */ +CGAL_INLINE_FUNCTION +void Camera::setType(Type type) { + // make ORTHOGRAPHIC frustum fit PERSPECTIVE (at least in plane normal to + // viewDirection(), passing through RAP). Done only when CHANGING type since + // orthoCoef_ may have been changed with a setPivotPoint() in the meantime. + if ((type == Camera::ORTHOGRAPHIC) && (type_ == Camera::PERSPECTIVE)) + orthoCoef_ = tan(fieldOfView() / 2.0); + type_ = type; + projectionMatrixIsUpToDate_ = false; +} + +/*! Sets the Camera frame(). + +If you want to move the Camera, use setPosition() and setOrientation() or one of +the Camera positioning methods (lookAt(), fitSphere(), showEntireScene()...) +instead. + +If you want to save the Camera position(), there's no need to call this method +either. Use addKeyFrameToPath() and playPath() instead. + +This method is actually mainly useful if you derive the ManipulatedCameraFrame +class and want to use an instance of your new class to move the Camera. + +A \c NULL \p mcf pointer will silently be ignored. The calling method is +responsible for deleting the previous frame() pointer if needed in order to +prevent memory leaks. */ +CGAL_INLINE_FUNCTION +void Camera::setFrame(ManipulatedCameraFrame *const mcf) { + if (!mcf) + return; + + if (frame_) { + disconnect(frame_, SIGNAL(modified()), this, SLOT(onFrameModified())); + } + + frame_ = mcf; + interpolationKfi_->setFrame(frame()); + + connect(frame_, SIGNAL(modified()), this, SLOT(onFrameModified())); + onFrameModified(); +} + +/*! Returns the distance from the Camera center to sceneCenter(), projected + along the Camera Z axis. Used by zNear() and zFar() to optimize the Z range. +*/ +CGAL_INLINE_FUNCTION +qreal Camera::distanceToSceneCenter() const { + return fabs((frame()->coordinatesOf(sceneCenter())).z); +} + +/*! Returns the \p halfWidth and \p halfHeight of the Camera orthographic + frustum. + + These values are only valid and used when the Camera is of type() + Camera::ORTHOGRAPHIC. They are expressed in OpenGL units and are used by + loadProjectionMatrix() to define the projection matrix using: \code glOrtho( + -halfWidth, halfWidth, -halfHeight, halfHeight, zNear(), zFar() ) \endcode + + These values are proportional to the Camera (z projected) distance to the + pivotPoint(). When zooming on the object, the Camera is translated forward \e + and its frustum is narrowed, making the object appear bigger on screen, as + intuitively expected. + + Overload this method to change this behavior if desired, as is done in the + standardCamera example. */ +CGAL_INLINE_FUNCTION +void Camera::getOrthoWidthHeight(GLdouble &halfWidth, + GLdouble &halfHeight) const { + const qreal dist = orthoCoef_ * fabs(cameraCoordinatesOf(pivotPoint()).z); + //#CONNECTION# fitScreenRegion + halfWidth = dist * ((aspectRatio() < 1.0) ? 1.0 : aspectRatio()); + halfHeight = dist * ((aspectRatio() < 1.0) ? 1.0 / aspectRatio() : 1.0); +} + +/*! Computes the projection matrix associated with the Camera. + + If type() is Camera::PERSPECTIVE, defines a \c GL_PROJECTION matrix similar to + what would \c gluPerspective() do using the fieldOfView(), window + aspectRatio(), zNear() and zFar() parameters. + + If type() is Camera::ORTHOGRAPHIC, the projection matrix is as what \c + glOrtho() would do. Frustum's width and height are set using + getOrthoWidthHeight(). + + Both types use zNear() and zFar() to place clipping planes. These values are + determined from sceneRadius() and sceneCenter() so that they best fit the scene + size. + + Use getProjectionMatrix() to retrieve this matrix. Overload + loadProjectionMatrix() if you want your Camera to use an exotic projection + matrix. + + \note You must call this method if your Camera is not associated with a + CGAL::QGLViewer and is used for offscreen computations (using + (un)projectedCoordinatesOf() for instance). loadProjectionMatrix() does it + otherwise. */ +CGAL_INLINE_FUNCTION +void Camera::computeProjectionMatrix() const { + if (projectionMatrixIsUpToDate_) + return; + + const qreal ZNear = zNear(); + const qreal ZFar = zFar(); + + switch (type()) { + case Camera::PERSPECTIVE: { + // #CONNECTION# all non null coefficients were set to 0.0 in constructor. + const qreal f = 1.0 / tan(fieldOfView() / 2.0); + projectionMatrix_[0] = f / aspectRatio(); + projectionMatrix_[5] = f; + projectionMatrix_[10] = (ZNear + ZFar) / (ZNear - ZFar); + projectionMatrix_[11] = -1.0; + projectionMatrix_[14] = 2.0 * ZNear * ZFar / (ZNear - ZFar); + projectionMatrix_[15] = 0.0; + // same as gluPerspective( 180.0*fieldOfView()/CGAL_PI, aspectRatio(), zNear(), + // zFar() ); + break; + } + case Camera::ORTHOGRAPHIC: { + GLdouble w, h; + getOrthoWidthHeight(w, h); + projectionMatrix_[0] = 1.0 / w; + projectionMatrix_[5] = 1.0 / h; + projectionMatrix_[10] = -2.0 / (ZFar - ZNear); + projectionMatrix_[11] = 0.0; + projectionMatrix_[14] = -(ZFar + ZNear) / (ZFar - ZNear); + projectionMatrix_[15] = 1.0; + // same as glOrtho( -w, w, -h, h, zNear(), zFar() ); + break; + } + } + + projectionMatrixIsUpToDate_ = true; +} + +/*! Computes the modelView matrix associated with the Camera's position() and + orientation(). + + This matrix converts from the world coordinates system to the Camera + coordinates system, so that coordinates can then be projected on screen using + the projection matrix (see computeProjectionMatrix()). + + Use getModelViewMatrix() to retrieve this matrix. + + \note You must call this method if your Camera is not associated with a + CGAL::QGLViewer and is used for offscreen computations (using + (un)projectedCoordinatesOf() for instance). loadModelViewMatrix() does it + otherwise. */ +CGAL_INLINE_FUNCTION +void Camera::computeModelViewMatrix() const { + if (modelViewMatrixIsUpToDate_) + return; + + const Quaternion q = frame()->orientation(); + + const qreal q00 = 2.0 * q[0] * q[0]; + const qreal q11 = 2.0 * q[1] * q[1]; + const qreal q22 = 2.0 * q[2] * q[2]; + + const qreal q01 = 2.0 * q[0] * q[1]; + const qreal q02 = 2.0 * q[0] * q[2]; + const qreal q03 = 2.0 * q[0] * q[3]; + + const qreal q12 = 2.0 * q[1] * q[2]; + const qreal q13 = 2.0 * q[1] * q[3]; + + const qreal q23 = 2.0 * q[2] * q[3]; + + modelViewMatrix_[0] = 1.0 - q11 - q22; + modelViewMatrix_[1] = q01 - q23; + modelViewMatrix_[2] = q02 + q13; + modelViewMatrix_[3] = 0.0; + + modelViewMatrix_[4] = q01 + q23; + modelViewMatrix_[5] = 1.0 - q22 - q00; + modelViewMatrix_[6] = q12 - q03; + modelViewMatrix_[7] = 0.0; + + modelViewMatrix_[8] = q02 - q13; + modelViewMatrix_[9] = q12 + q03; + modelViewMatrix_[10] = 1.0 - q11 - q00; + modelViewMatrix_[11] = 0.0; + + const Vec t = q.inverseRotate(frame()->position()); + + modelViewMatrix_[12] = -t.x; + modelViewMatrix_[13] = -t.y; + modelViewMatrix_[14] = -t.z; + modelViewMatrix_[15] = 1.0; + + modelViewMatrixIsUpToDate_ = true; +} + +/*! Loads the OpenGL \c GL_PROJECTION matrix with the Camera projection matrix. + + The Camera projection matrix is computed using computeProjectionMatrix(). + + When \p reset is \c true (default), the method clears the previous projection + matrix by calling \c glLoadIdentity before setting the matrix. Setting \p reset + to \c false is useful for \c GL_SELECT mode, to combine the pushed matrix with + a picking matrix. See CGAL::QGLViewer::beginSelection() for details. + + This method is used by CGAL::QGLViewer::preDraw() (called before user's + CGAL::QGLViewer::draw() method) to set the \c GL_PROJECTION matrix according to the + viewer's CGAL::QGLViewer::camera() settings. + + Use getProjectionMatrix() to retrieve this matrix. Overload this method if you + want your Camera to use an exotic projection matrix. See also + loadModelViewMatrix(). + + \attention \c glMatrixMode is set to \c GL_PROJECTION. + + \attention If you use several OpenGL contexts and bypass the Qt main refresh + loop, you should call QOpenGLWidget::makeCurrent() before this method in order + to activate the right OpenGL context. */ +CGAL_INLINE_FUNCTION +void Camera::loadProjectionMatrix(bool reset) const { + // WARNING: makeCurrent must be called by every calling method + gl()->glMatrixMode(GL_PROJECTION); + + if (reset) + gl()->glLoadIdentity(); + + computeProjectionMatrix(); + + gl()->glMultMatrixd(projectionMatrix_); +} + +/*! Loads the OpenGL \c GL_MODELVIEW matrix with the modelView matrix + corresponding to the Camera. + + Calls computeModelViewMatrix() to compute the Camera's modelView matrix. + + This method is used by CGAL::QGLViewer::preDraw() (called before user's + CGAL::QGLViewer::draw() method) to set the \c GL_MODELVIEW matrix according to the + viewer's CGAL::QGLViewer::camera() position() and orientation(). + + As a result, the vertices used in CGAL::QGLViewer::draw() can be defined in the so + called world coordinate system. They are multiplied by this matrix to get + converted to the Camera coordinate system, before getting projected using the + \c GL_PROJECTION matrix (see loadProjectionMatrix()). + + When \p reset is \c true (default), the method loads (overwrites) the \c + GL_MODELVIEW matrix. Setting \p reset to \c false simply calls \c glMultMatrixd + (might be useful for some applications). + + Overload this method or simply call glLoadMatrixd() at the beginning of + CGAL::QGLViewer::draw() if you want your Camera to use an exotic modelView matrix. + See also loadProjectionMatrix(). + + getModelViewMatrix() returns the 4x4 modelView matrix. + + \attention glMatrixMode is set to \c GL_MODELVIEW + + \attention If you use several OpenGL contexts and bypass the Qt main refresh + loop, you should call QOpenGLWidget::makeCurrent() before this method in order + to activate the right OpenGL context. */ +CGAL_INLINE_FUNCTION +void Camera::loadModelViewMatrix(bool reset) const { + // WARNING: makeCurrent must be called by every calling method + gl()->glMatrixMode(GL_MODELVIEW); + computeModelViewMatrix(); + if (reset) + gl()->glLoadMatrixd(modelViewMatrix_); + else + gl()->glMultMatrixd(modelViewMatrix_); +} + +/*! Same as loadProjectionMatrix() but for a stereo setup. + + Only the Camera::PERSPECTIVE type() is supported for stereo mode. See + CGAL::QGLViewer::setStereoDisplay(). + + Uses focusDistance(), IODistance(), and physicalScreenWidth() to compute + cameras offset and asymmetric frustums. + + When \p leftBuffer is \c true, computes the projection matrix associated to the + left eye (right eye otherwise). See also loadModelViewMatrixStereo(). + + See the stereoViewer and the anaglyph examples for an + illustration. + + To retrieve this matrix, use a code like: + \code + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + loadProjectionMatrixStereo(left_or_right); + glGetDoublev(GL_PROJECTION_MATRIX, m); + glPopMatrix(); + \endcode + Note that getProjectionMatrix() always returns the mono-vision matrix. + + \attention glMatrixMode is set to \c GL_PROJECTION. */ +CGAL_INLINE_FUNCTION +void Camera::loadProjectionMatrixStereo(bool leftBuffer) const { + qreal left, right, bottom, top; + qreal screenHalfWidth, halfWidth, side, shift, delta; + + gl()->glMatrixMode(GL_PROJECTION); + gl()->glLoadIdentity(); + + switch (type()) { + case Camera::PERSPECTIVE: + // compute half width of screen, + // corresponding to zero parallax plane to deduce decay of cameras + screenHalfWidth = focusDistance() * tan(horizontalFieldOfView() / 2.0); + shift = screenHalfWidth * IODistance() / physicalScreenWidth(); + // should be * current y / y total + // to take into account that the window doesn't cover the entire screen + + // compute half width of "view" at znear and the delta corresponding to + // the shifted camera to deduce what to set for asymmetric frustums + halfWidth = zNear() * tan(horizontalFieldOfView() / 2.0); + delta = shift * zNear() / focusDistance(); + side = leftBuffer ? -1.0 : 1.0; + + left = -halfWidth + side * delta; + right = halfWidth + side * delta; + top = halfWidth / aspectRatio(); + bottom = -top; + gl()->glFrustum(left, right, bottom, top, zNear(), zFar()); + break; + + case Camera::ORTHOGRAPHIC: + qWarning("Camera::setProjectionMatrixStereo: Stereo not available with " + "Ortho mode"); + break; + } +} + +/*! Same as loadModelViewMatrix() but for a stereo setup. + + Only the Camera::PERSPECTIVE type() is supported for stereo mode. See + CGAL::QGLViewer::setStereoDisplay(). + + The modelView matrix is almost identical to the mono-vision one. It is simply + translated along its horizontal axis by a value that depends on stereo + parameters (see focusDistance(), IODistance(), and physicalScreenWidth()). + + When \p leftBuffer is \c true, computes the modelView matrix associated to the + left eye (right eye otherwise). + + loadProjectionMatrixStereo() explains how to retrieve to resulting matrix. + + See the stereoViewer and the anaglyph examples for an + illustration. + + \attention glMatrixMode is set to \c GL_MODELVIEW. */ +CGAL_INLINE_FUNCTION +void Camera::loadModelViewMatrixStereo(bool leftBuffer) const { + // WARNING: makeCurrent must be called by every calling method + gl()->glMatrixMode(GL_MODELVIEW); + + qreal halfWidth = focusDistance() * tan(horizontalFieldOfView() / 2.0); + qreal shift = + halfWidth * IODistance() / + physicalScreenWidth(); // * current window width / full screen width + + computeModelViewMatrix(); + if (leftBuffer) + modelViewMatrix_[12] -= shift; + else + modelViewMatrix_[12] += shift; + gl()->glLoadMatrixd(modelViewMatrix_); +} + +/*! Fills \p m with the Camera projection matrix values. + + Based on computeProjectionMatrix() to make sure the Camera projection matrix is + up to date. + + This matrix only reflects the Camera's internal parameters and it may differ + from the \c GL_PROJECTION matrix retrieved using \c + glGetDoublev(GL_PROJECTION_MATRIX, m). It actually represents the state of the + \c GL_PROJECTION after CGAL::QGLViewer::preDraw(), at the beginning of + CGAL::QGLViewer::draw(). If you modified the \c GL_PROJECTION matrix (for instance + using CGAL::QGLViewer::startScreenCoordinatesSystem()), the two results differ. + + The result is an OpenGL 4x4 matrix, which is given in \e column-major order + (see \c glMultMatrix man page for details). + + See also getModelViewMatrix() and setFromProjectionMatrix(). */ +CGAL_INLINE_FUNCTION +void Camera::getProjectionMatrix(GLdouble m[16]) const { + computeProjectionMatrix(); + for (unsigned short i = 0; i < 16; ++i) + m[i] = projectionMatrix_[i]; +} + +/*! Overloaded getProjectionMatrix(GLdouble m[16]) method using a \c GLfloat + * array instead. */ +CGAL_INLINE_FUNCTION +void Camera::getProjectionMatrix(GLfloat m[16]) const { + static GLdouble mat[16]; + getProjectionMatrix(mat); + for (unsigned short i = 0; i < 16; ++i) + m[i] = float(mat[i]); +} + +/*! Fills \p m with the Camera modelView matrix values. + + First calls computeModelViewMatrix() to define the Camera modelView matrix. + + Note that this matrix may \e not be the one you would get from a \c + glGetDoublev(GL_MODELVIEW_MATRIX, m). It actually represents the state of the + \c GL_MODELVIEW after CGAL::QGLViewer::preDraw(), at the \e beginning of + CGAL::QGLViewer::draw(). It converts from the world to the Camera coordinate system. + As soon as you modify the \c GL_MODELVIEW in your CGAL::QGLViewer::draw() method + (using glTranslate, glRotate... or similar methods), the two matrices differ. + + The result is an OpenGL 4x4 matrix, which is given in \e column-major order + (see \c glMultMatrix man page for details). + + See also getProjectionMatrix() and setFromModelViewMatrix(). */ +CGAL_INLINE_FUNCTION +void Camera::getModelViewMatrix(GLdouble m[16]) const { + // May not be needed, but easier like this. + // Prevents from retrieving matrix in stereo mode -> overwrites shifted value. + computeModelViewMatrix(); + for (unsigned short i = 0; i < 16; ++i) + m[i] = modelViewMatrix_[i]; +} + +/*! Overloaded getModelViewMatrix(GLdouble m[16]) method using a \c GLfloat + * array instead. */ +CGAL_INLINE_FUNCTION +void Camera::getModelViewMatrix(GLfloat m[16]) const { + static GLdouble mat[16]; + getModelViewMatrix(mat); + for (unsigned short i = 0; i < 16; ++i) + m[i] = float(mat[i]); +} + +/*! Fills \p m with the product of the ModelView and Projection matrices. + + Calls getModelViewMatrix() and getProjectionMatrix() and then fills \p m with + the product of these two matrices. */ +CGAL_INLINE_FUNCTION +void Camera::getModelViewProjectionMatrix(GLdouble m[16]) const { + GLdouble mv[16]; + GLdouble proj[16]; + getModelViewMatrix(mv); + getProjectionMatrix(proj); + + for (unsigned short i = 0; i < 4; ++i) { + for (unsigned short j = 0; j < 4; ++j) { + qreal sum = 0.0; + for (unsigned short k = 0; k < 4; ++k) + sum += proj[i + 4 * k] * mv[k + 4 * j]; + m[i + 4 * j] = sum; + } + } +} + +/*! Overloaded getModelViewProjectionMatrix(GLdouble m[16]) method using a \c + * GLfloat array instead. */ +CGAL_INLINE_FUNCTION +void Camera::getModelViewProjectionMatrix(GLfloat m[16]) const { + static GLdouble mat[16]; + getModelViewProjectionMatrix(mat); + for (unsigned short i = 0; i < 16; ++i) + m[i] = float(mat[i]); +} + +/*! Sets the sceneRadius() value. Negative values are ignored. + +\attention This methods also sets focusDistance() to sceneRadius() / +tan(fieldOfView()/2) and flySpeed() to 1% of sceneRadius(). */ +CGAL_INLINE_FUNCTION +void Camera::setSceneRadius(qreal radius) { + if (radius <= 0.0) { + qWarning("Scene radius must be positive - Ignoring value"); + return; + } + + sceneRadius_ = radius; + projectionMatrixIsUpToDate_ = false; + + setFocusDistance(sceneRadius() / tan(fieldOfView() / 2.0)); + + frame()->setFlySpeed(0.01 * sceneRadius()); +} + +/*! Similar to setSceneRadius() and setSceneCenter(), but the scene limits are + defined by a (world axis aligned) bounding box. */ +CGAL_INLINE_FUNCTION +void Camera::setSceneBoundingBox(const Vec &min, const Vec &max) { + setSceneCenter((min + max) / 2.0); + setSceneRadius(0.5 * (max - min).norm()); +} + +/*! Sets the sceneCenter(). + + \attention This method also sets the pivotPoint() to sceneCenter(). */ +CGAL_INLINE_FUNCTION +void Camera::setSceneCenter(const Vec ¢er) { + sceneCenter_ = center; + setPivotPoint(sceneCenter()); + projectionMatrixIsUpToDate_ = false; +} + +/*! setSceneCenter() to the result of pointUnderPixel(\p pixel). + + Returns \c true if a pointUnderPixel() was found and sceneCenter() was + actually changed. + + See also setPivotPointFromPixel(). See the pointUnderPixel() documentation. */ +CGAL_INLINE_FUNCTION +bool Camera::setSceneCenterFromPixel(const QPoint &pixel) { + bool found; + Vec point = pointUnderPixel(pixel, found); + if (found) + setSceneCenter(point); + return found; +} + +/*! Changes the pivotPoint() to \p point (defined in the world coordinate + * system). */ +CGAL_INLINE_FUNCTION +void Camera::setPivotPoint(const Vec &point) { + const qreal prevDist = fabs(cameraCoordinatesOf(pivotPoint()).z); + + // If frame's RAP is set directly, projectionMatrixIsUpToDate_ should also be + // set to false to ensure proper recomputation of the ORTHO projection matrix. + frame()->setPivotPoint(point); + + // orthoCoef_ is used to compensate for changes of the pivotPoint, so that the + // image does not change when the pivotPoint is changed in ORTHOGRAPHIC mode. + const qreal newDist = fabs(cameraCoordinatesOf(pivotPoint()).z); + // Prevents division by zero when rap is set to camera position + if ((prevDist > 1E-9) && (newDist > 1E-9)) + orthoCoef_ *= prevDist / newDist; + projectionMatrixIsUpToDate_ = false; +} + +/*! The pivotPoint() is set to the point located under \p pixel on screen. + +Returns \c true if a pointUnderPixel() was found. If no point was found under \p +pixel, the pivotPoint() is left unchanged. + +\p pixel is expressed in Qt format (origin in the upper left corner of the +window). See pointUnderPixel(). + +See also setSceneCenterFromPixel(). */ +CGAL_INLINE_FUNCTION +bool Camera::setPivotPointFromPixel(const QPoint &pixel) { + bool found; + Vec point = pointUnderPixel(pixel, found); + if (found) + setPivotPoint(point); + return found; +} + +/*! Returns the ratio between pixel and OpenGL units at \p position. + + A line of \c n * pixelGLRatio() OpenGL units, located at \p position in the + world coordinates system, will be projected with a length of \c n pixels on + screen. + + Use this method to scale objects so that they have a constant pixel size on + screen. The following code will draw a 20 pixel line, starting at sceneCenter() + and always directed along the screen vertical direction: \code + glBegin(GL_LINES); + glVertex3fv(sceneCenter()); + glVertex3fv(sceneCenter() + 20 * pixelGLRatio(sceneCenter()) * + camera()->upVector()); glEnd(); \endcode */ +CGAL_INLINE_FUNCTION +qreal Camera::pixelGLRatio(const Vec &position) const { + switch (type()) { + case Camera::PERSPECTIVE: + return 2.0 * fabs((frame()->coordinatesOf(position)).z) * + tan(fieldOfView() / 2.0) / screenHeight(); + case Camera::ORTHOGRAPHIC: { + GLdouble w, h; + getOrthoWidthHeight(w, h); + return 2.0 * h / screenHeight(); + } + } + // Bad compilers complain + return 1.0; +} + +/*! Changes the Camera fieldOfView() so that the entire scene (defined by + CGAL::QGLViewer::sceneCenter() and CGAL::QGLViewer::sceneRadius()) is visible from the + Camera position(). + + The position() and orientation() of the Camera are not modified and you first + have to orientate the Camera in order to actually see the scene (see lookAt(), + showEntireScene() or fitSphere()). + + This method is especially useful for \e shadow \e maps computation. Use the + Camera positioning tools (setPosition(), lookAt()) to position a Camera at the + light position. Then use this method to define the fieldOfView() so that the + shadow map resolution is optimally used: \code + // The light camera needs size hints in order to optimize its fieldOfView + lightCamera->setSceneRadius(sceneRadius()); + lightCamera->setSceneCenter(sceneCenter()); + + // Place the light camera. + lightCamera->setPosition(lightFrame->position()); + lightCamera->lookAt(sceneCenter()); + lightCamera->setFOVToFitScene(); + \endcode + + See the (soon available) shadowMap contribution example for a practical + implementation. + + \attention The fieldOfView() is clamped to CGAL_PI/2.0. This happens when the + Camera is at a distance lower than sqrt(2.0) * sceneRadius() from the + sceneCenter(). It optimizes the shadow map resolution, although it may miss + some parts of the scene. */ +CGAL_INLINE_FUNCTION +void Camera::setFOVToFitScene() { + if (distanceToSceneCenter() > sqrt(2.0) * sceneRadius()) + setFieldOfView(2.0 * asin(sceneRadius() / distanceToSceneCenter())); + else + setFieldOfView(CGAL_PI / 2.0); +} + +/*! Makes the Camera smoothly zoom on the pointUnderPixel() \p pixel. + + Nothing happens if no pointUnderPixel() is found. Otherwise a + KeyFrameInterpolator is created that animates the Camera on a one second path + that brings the Camera closer to the point under \p pixel. + + See also interpolateToFitScene(). */ +CGAL_INLINE_FUNCTION +void Camera::interpolateToZoomOnPixel(const QPoint &pixel) { + const qreal coef = 0.1; + + bool found; + Vec target = pointUnderPixel(pixel, found); + + if (!found) + return; + + if (interpolationKfi_->interpolationIsStarted()) + interpolationKfi_->stopInterpolation(); + + interpolationKfi_->deletePath(); + interpolationKfi_->addKeyFrame(*(frame())); + + interpolationKfi_->addKeyFrame( + Frame(0.3 * frame()->position() + 0.7 * target, frame()->orientation()), + 0.4); + + // Small hack: attach a temporary frame to take advantage of lookAt without + // modifying frame + static ManipulatedCameraFrame *tempFrame = new ManipulatedCameraFrame(); + ManipulatedCameraFrame *const originalFrame = frame(); + tempFrame->setPosition(coef * frame()->position() + (1.0 - coef) * target); + tempFrame->setOrientation(frame()->orientation()); + setFrame(tempFrame); + lookAt(target); + setFrame(originalFrame); + + interpolationKfi_->addKeyFrame(*(tempFrame), 1.0); + + interpolationKfi_->startInterpolation(); +} + +/*! Interpolates the Camera on a one second KeyFrameInterpolator path so that + the entire scene fits the screen at the end. + + The scene is defined by its sceneCenter() and its sceneRadius(). See + showEntireScene(). + + The orientation() of the Camera is not modified. See also + interpolateToZoomOnPixel(). */ +CGAL_INLINE_FUNCTION +void Camera::interpolateToFitScene() { + if (interpolationKfi_->interpolationIsStarted()) + interpolationKfi_->stopInterpolation(); + + interpolationKfi_->deletePath(); + interpolationKfi_->addKeyFrame(*(frame())); + + // Small hack: attach a temporary frame to take advantage of lookAt without + // modifying frame + static ManipulatedCameraFrame *tempFrame = new ManipulatedCameraFrame(); + ManipulatedCameraFrame *const originalFrame = frame(); + tempFrame->setPosition(frame()->position()); + tempFrame->setOrientation(frame()->orientation()); + setFrame(tempFrame); + showEntireScene(); + setFrame(originalFrame); + + interpolationKfi_->addKeyFrame(*(tempFrame)); + + interpolationKfi_->startInterpolation(); +} + +/*! Smoothly interpolates the Camera on a KeyFrameInterpolator path so that it + goes to \p fr. + + \p fr is expressed in world coordinates. \p duration tunes the interpolation + speed (default is 1 second). + + See also interpolateToFitScene() and interpolateToZoomOnPixel(). */ +CGAL_INLINE_FUNCTION +void Camera::interpolateTo(const Frame &fr, qreal duration) { + if (interpolationKfi_->interpolationIsStarted()) + interpolationKfi_->stopInterpolation(); + + interpolationKfi_->deletePath(); + interpolationKfi_->addKeyFrame(*(frame())); + interpolationKfi_->addKeyFrame(fr, duration); + + interpolationKfi_->startInterpolation(); +} + +/*! Returns the coordinates of the 3D point located at pixel (x,y) on screen. + + Calls a \c glReadPixel to get the pixel depth and applies an + unprojectedCoordinatesOf() to the result. \p found indicates whether a point + was found or not (i.e. background pixel, result's depth is zFar() in that + case). + + \p x and \p y are expressed in pixel units with an origin in the upper left + corner. Use screenHeight() - y to convert to OpenGL standard. + + \attention This method assumes that a GL context is available, and that its + content was drawn using the Camera (i.e. using its projection and modelview + matrices). This method hence cannot be used for offscreen Camera computations. + Use cameraCoordinatesOf() and worldCoordinatesOf() to perform similar + operations in that case. + + \note The precision of the z-Buffer highly depends on how the zNear() and + zFar() values are fitted to your scene. Loose boundaries will result in + imprecision along the viewing direction. */ +CGAL_INLINE_FUNCTION +Vec Camera::pointUnderPixel(const QPoint &pixel, bool &found) const { + float depth; + // Qt uses upper corner for its origin while GL uses the lower corner. + dynamic_cast(parent())->glReadPixels(pixel.x(), screenHeight() - 1 - pixel.y(), 1, 1, + GL_DEPTH_COMPONENT, GL_FLOAT, &depth); + found = depth < 1.0; + Vec point(pixel.x(), pixel.y(), depth); + point = unprojectedCoordinatesOf(point); + return point; +} + +/*! Moves the Camera so that the entire scene is visible. + + Simply calls fitSphere() on a sphere defined by sceneCenter() and + sceneRadius(). + + You will typically use this method in CGAL::QGLViewer::init() after you defined a new + sceneRadius(). */ +CGAL_INLINE_FUNCTION +void Camera::showEntireScene() { fitSphere(sceneCenter(), sceneRadius()); } + +/*! Moves the Camera so that its sceneCenter() is projected on the center of the + window. The orientation() and fieldOfView() are unchanged. + + Simply projects the current position on a line passing through sceneCenter(). + See also showEntireScene().*/ +CGAL_INLINE_FUNCTION +void Camera::centerScene() { + frame()->projectOnLine(sceneCenter(), viewDirection()); +} + +/*! Sets the Camera orientation(), so that it looks at point \p target (defined + in the world coordinate system). + + The Camera position() is not modified. Simply setViewDirection(). + + See also setUpVector(), setOrientation(), showEntireScene(), fitSphere() and + fitBoundingBox(). */ +CGAL_INLINE_FUNCTION +void Camera::lookAt(const Vec &target) { + setViewDirection(target - position()); +} + +/*! Moves the Camera so that the sphere defined by (\p center, \p radius) is + visible and fits in the frustum. + + The Camera is simply translated to center the sphere in the screen and make it + fit the frustum. Its orientation() and its fieldOfView() are unchanged. + + You should therefore orientate the Camera before you call this method. See + lookAt(), setOrientation() and setUpVector(). */ +CGAL_INLINE_FUNCTION +void Camera::fitSphere(const Vec ¢er, qreal radius) { + qreal distance = 0.0; + switch (type()) { + case Camera::PERSPECTIVE: { + const qreal yview = radius / sin(fieldOfView() / 2.0); + const qreal xview = radius / sin(horizontalFieldOfView() / 2.0); + distance = qMax(xview, yview); + break; + } + case Camera::ORTHOGRAPHIC: { + distance = + ((center - pivotPoint()) * viewDirection()) + (radius / orthoCoef_); + break; + } + } + Vec newPos(center - distance * viewDirection()); + frame()->setPositionWithConstraint(newPos); +} + +/*! Moves the Camera so that the (world axis aligned) bounding box (\p min, \p + max) is entirely visible, using fitSphere(). */ +CGAL_INLINE_FUNCTION +void Camera::fitBoundingBox(const Vec &min, const Vec &max) { + qreal diameter = qMax(fabs(max[1] - min[1]), fabs(max[0] - min[0])); + diameter = qMax(fabs(max[2] - min[2]), diameter); + fitSphere(0.5 * (min + max), 0.5 * diameter); +} + +/*! Moves the Camera so that the rectangular screen region defined by \p + rectangle (pixel units, with origin in the upper left corner) fits the screen. + + The Camera is translated (its orientation() is unchanged) so that \p rectangle + is entirely visible. Since the pixel coordinates only define a \e frustum in + 3D, it's the intersection of this frustum with a plane (orthogonal to the + viewDirection() and passing through the sceneCenter()) that is used to define + the 3D rectangle that is eventually fitted. */ +CGAL_INLINE_FUNCTION +void Camera::fitScreenRegion(const QRect &rectangle) { + const Vec vd = viewDirection(); + const qreal distToPlane = distanceToSceneCenter(); + const QPoint center = rectangle.center(); + + Vec orig, dir; + convertClickToLine(center, orig, dir); + Vec newCenter = orig + distToPlane / (dir * vd) * dir; + + convertClickToLine(QPoint(rectangle.x(), center.y()), orig, dir); + const Vec pointX = orig + distToPlane / (dir * vd) * dir; + + convertClickToLine(QPoint(center.x(), rectangle.y()), orig, dir); + const Vec pointY = orig + distToPlane / (dir * vd) * dir; + + qreal distance = 0.0; + switch (type()) { + case Camera::PERSPECTIVE: { + const qreal distX = + (pointX - newCenter).norm() / sin(horizontalFieldOfView() / 2.0); + const qreal distY = (pointY - newCenter).norm() / sin(fieldOfView() / 2.0); + distance = qMax(distX, distY); + break; + } + case Camera::ORTHOGRAPHIC: { + const qreal dist = ((newCenter - pivotPoint()) * vd); + //#CONNECTION# getOrthoWidthHeight + const qreal distX = (pointX - newCenter).norm() / orthoCoef_ / + ((aspectRatio() < 1.0) ? 1.0 : aspectRatio()); + const qreal distY = (pointY - newCenter).norm() / orthoCoef_ / + ((aspectRatio() < 1.0) ? 1.0 / aspectRatio() : 1.0); + distance = dist + qMax(distX, distY); + break; + } + } + + Vec newPos(newCenter - distance * vd); + frame()->setPositionWithConstraint(newPos); +} + +/*! Rotates the Camera so that its upVector() becomes \p up (defined in the + world coordinate system). + + The Camera is rotated around an axis orthogonal to \p up and to the current + upVector() direction. Use this method in order to define the Camera horizontal + plane. + + When \p noMove is set to \c false, the orientation modification is compensated + by a translation, so that the pivotPoint() stays projected at the same position + on screen. This is especially useful when the Camera is used as an observer of + the scene (default mouse binding). + + When \p noMove is \c true (default), the Camera position() is left unchanged, + which is an intuitive behavior when the Camera is in a walkthrough fly mode + (see the CGAL::QGLViewer::MOVE_FORWARD and CGAL::QGLViewer::MOVE_BACKWARD + CGAL::QGLViewer::MouseAction). + + The frame()'s ManipulatedCameraFrame::sceneUpVector() is set accordingly. + + See also setViewDirection(), lookAt() and setOrientation(). */ +CGAL_INLINE_FUNCTION +void Camera::setUpVector(const Vec &up, bool noMove) { + Quaternion q(Vec(0.0, 1.0, 0.0), frame()->transformOf(up)); + + if (!noMove) + frame()->setPosition(pivotPoint() - + (frame()->orientation() * q) + .rotate(frame()->coordinatesOf(pivotPoint()))); + + frame()->rotate(q); + + // Useful in fly mode to keep the horizontal direction. + frame()->updateSceneUpVector(); +} + +/*! Sets the orientation() of the Camera using polar coordinates. + + \p theta rotates the Camera around its Y axis, and \e then \p phi rotates it + around its X axis. The polar coordinates are defined in the world coordinates + system: \p theta = \p phi = 0 means that the Camera is directed towards the + world Z axis. Both angles are expressed in radians. + + See also setUpVector(). The position() of the Camera is unchanged, you may want + to call showEntireScene() after this method to move the Camera. + + This method can be useful to create Quicktime VR panoramic sequences, see the + CGAL::QGLViewer::saveSnapshot() documentation for details. */ +CGAL_INLINE_FUNCTION +void Camera::setOrientation(qreal theta, qreal phi) { + Vec axis(0.0, 1.0, 0.0); + const Quaternion rot1(axis, theta); + axis = Vec(-cos(theta), 0.0, sin(theta)); + const Quaternion rot2(axis, phi); + setOrientation(rot1 * rot2); +} + +/*! Sets the Camera orientation(), defined in the world coordinate system. */ +CGAL_INLINE_FUNCTION +void Camera::setOrientation(const Quaternion &q) { + frame()->setOrientation(q); + frame()->updateSceneUpVector(); +} + +/*! Rotates the Camera so that its viewDirection() is \p direction (defined in + the world coordinate system). + + The Camera position() is not modified. The Camera is rotated so that the + horizon (defined by its upVector()) is preserved. See also lookAt() and + setUpVector(). */ +CGAL_INLINE_FUNCTION +void Camera::setViewDirection(const Vec &direction) { + if (direction.squaredNorm() < 1E-10) + return; + + Vec xAxis = direction ^ upVector(); + if (xAxis.squaredNorm() < 1E-10) { + // target is aligned with upVector, this means a rotation around X axis + // X axis is then unchanged, let's keep it ! + xAxis = frame()->inverseTransformOf(Vec(1.0, 0.0, 0.0)); + } + + Quaternion q; + q.setFromRotatedBasis(xAxis, xAxis ^ direction, -direction); + frame()->setOrientationWithConstraint(q); +} + +// Compute a 3 by 3 determinant. +static qreal det(qreal m00, qreal m01, qreal m02, qreal m10, qreal m11, + qreal m12, qreal m20, qreal m21, qreal m22) { + return m00 * m11 * m22 + m01 * m12 * m20 + m02 * m10 * m21 - m20 * m11 * m02 - + m10 * m01 * m22 - m00 * m21 * m12; +} + +// Computes the index of element [i][j] in a \c qreal matrix[3][4]. +static inline unsigned int ind(unsigned int i, unsigned int j) { + return (i * 4 + j); +} + +/*! Returns the Camera position (the eye), defined in the world coordinate +system. + +Use setPosition() to set the Camera position. Other convenient methods are +showEntireScene() or fitSphere(). Actually returns \c frame()->position(). + +This position corresponds to the projection center of a Camera::PERSPECTIVE +Camera. It is not located in the image plane, which is at a zNear() distance +ahead. */ +CGAL_INLINE_FUNCTION +Vec Camera::position() const { return frame()->position(); } + +/*! Returns the normalized up vector of the Camera, defined in the world +coordinate system. + +Set using setUpVector() or setOrientation(). It is orthogonal to viewDirection() +and to rightVector(). + +It corresponds to the Y axis of the associated frame() (actually returns +frame()->inverseTransformOf(Vec(0.0, 1.0, 0.0)) ). */ +CGAL_INLINE_FUNCTION +Vec Camera::upVector() const { + return frame()->inverseTransformOf(Vec(0.0, 1.0, 0.0)); +} +/*! Returns the normalized view direction of the Camera, defined in the world +coordinate system. + +Change this value using setViewDirection(), lookAt() or setOrientation(). It is +orthogonal to upVector() and to rightVector(). + +This corresponds to the negative Z axis of the frame() ( +frame()->inverseTransformOf(Vec(0.0, 0.0, -1.0)) ). */ +CGAL_INLINE_FUNCTION +Vec Camera::viewDirection() const { + return frame()->inverseTransformOf(Vec(0.0, 0.0, -1.0)); +} + +/*! Returns the normalized right vector of the Camera, defined in the world +coordinate system. + +This vector lies in the Camera horizontal plane, directed along the X axis +(orthogonal to upVector() and to viewDirection()). Set using setUpVector(), +lookAt() or setOrientation(). + +Simply returns frame()->inverseTransformOf(Vec(1.0, 0.0, 0.0)). */ +CGAL_INLINE_FUNCTION +Vec Camera::rightVector() const { + return frame()->inverseTransformOf(Vec(1.0, 0.0, 0.0)); +} + +/*! Returns the Camera orientation, defined in the world coordinate system. + +Actually returns \c frame()->orientation(). Use setOrientation(), setUpVector() +or lookAt() to set the Camera orientation. */ +CGAL_INLINE_FUNCTION +Quaternion Camera::orientation() const { return frame()->orientation(); } + +/*! Sets the Camera position() (the eye), defined in the world coordinate + * system. */ +CGAL_INLINE_FUNCTION +void Camera::setPosition(const Vec &pos) { frame()->setPosition(pos); } + +/*! Returns the Camera frame coordinates of a point \p src defined in world +coordinates. + +worldCoordinatesOf() performs the inverse transformation. + +Note that the point coordinates are simply converted in a different coordinate +system. They are not projected on screen. Use projectedCoordinatesOf() for that. +*/ +CGAL_INLINE_FUNCTION +Vec Camera::cameraCoordinatesOf(const Vec &src) const { + return frame()->coordinatesOf(src); +} + +/*! Returns the world coordinates of the point whose position \p src is defined +in the Camera coordinate system. + +cameraCoordinatesOf() performs the inverse transformation. */ +CGAL_INLINE_FUNCTION +Vec Camera::worldCoordinatesOf(const Vec &src) const { + return frame()->inverseCoordinatesOf(src); +} + +/*! Returns the fly speed of the Camera. + +Simply returns frame()->flySpeed(). See the ManipulatedCameraFrame::flySpeed() +documentation. This value is only meaningful when the MouseAction bindings is +CGAL::QGLViewer::MOVE_FORWARD or CGAL::QGLViewer::MOVE_BACKWARD. + +Set to 1% of the sceneRadius() by setSceneRadius(). See also setFlySpeed(). */ +CGAL_INLINE_FUNCTION +qreal Camera::flySpeed() const { return frame()->flySpeed(); } + +/*! Sets the Camera flySpeed(). + +\attention This value is modified by setSceneRadius(). */ +CGAL_INLINE_FUNCTION +void Camera::setFlySpeed(qreal speed) { frame()->setFlySpeed(speed); } + +/*! The point the Camera pivots around with the CGAL::QGLViewer::ROTATE mouse binding. +Defined in world coordinate system. + +Default value is the sceneCenter(). + +\attention setSceneCenter() changes this value. */ +CGAL_INLINE_FUNCTION +Vec Camera::pivotPoint() const { return frame()->pivotPoint(); } + +/*! Sets the Camera's position() and orientation() from an OpenGL ModelView +matrix. + +This enables a Camera initialisation from an other OpenGL application. \p +modelView is a 16 GLdouble vector representing a valid OpenGL ModelView matrix, +such as one can get using: \code GLdouble mvm[16]; +glGetDoublev(GL_MODELVIEW_MATRIX, mvm); +myCamera->setFromModelViewMatrix(mvm); +\endcode + +After this method has been called, getModelViewMatrix() returns a matrix +equivalent to \p modelView. + +Only the orientation() and position() of the Camera are modified. + +\note If you defined your matrix as \c GLdouble \c mvm[4][4], pass \c +&(mvm[0][0]) as a parameter. */ +CGAL_INLINE_FUNCTION +void Camera::setFromModelViewMatrix(const GLdouble *const modelViewMatrix) { + // Get upper left (rotation) matrix + qreal upperLeft[3][3]; + for (int i = 0; i < 3; ++i) + for (int j = 0; j < 3; ++j) + upperLeft[i][j] = modelViewMatrix[i * 4 + j]; + + // Transform upperLeft into the associated Quaternion + Quaternion q; + q.setFromRotationMatrix(upperLeft); + + setOrientation(q); + setPosition(-q.rotate( + Vec(modelViewMatrix[12], modelViewMatrix[13], modelViewMatrix[14]))); +} + +/*! Defines the Camera position(), orientation() and fieldOfView() from a + projection matrix. + + \p matrix has to be given in the format used by vision algorithm. It has 3 + lines and 4 columns. It transforms a point from the world homogeneous + coordinate system (4 coordinates: \c sx, \c sy, \c sz and \c s) into a point in + the screen homogeneous coordinate system (3 coordinates: \c sx, \c sy, and \c + s, where \c x and \c y are the pixel coordinates on the screen). + + Its three lines correspond to the homogeneous coordinates of the normals to the + planes x=0, y=0 and z=0, defined in the Camera coordinate system. + + The elements of the matrix are ordered in line major order: you can call \c + setFromProjectionMatrix(&(matrix[0][0])) if you defined your matrix as a \c + qreal \c matrix[3][4]. + + \attention Passing the result of getProjectionMatrix() or getModelViewMatrix() + to this method is not possible (purposefully incompatible matrix dimensions). + \p matrix is more likely to be the product of these two matrices, without the + last line. + + Use setFromModelViewMatrix() to set position() and orientation() from a \c + GL_MODELVIEW matrix. fieldOfView() can also be retrieved from a \e perspective + \c GL_PROJECTION matrix using 2.0 * atan(1.0/projectionMatrix[5]). + + This code was written by Sylvain Paris. */ +CGAL_INLINE_FUNCTION +void Camera::setFromProjectionMatrix(const qreal matrix[12]) { + // The 3 lines of the matrix are the normals to the planes x=0, y=0, z=0 + // in the camera CS. As we normalize them, we do not need the 4th coordinate. + Vec line_0(matrix[ind(0, 0)], matrix[ind(0, 1)], matrix[ind(0, 2)]); + Vec line_1(matrix[ind(1, 0)], matrix[ind(1, 1)], matrix[ind(1, 2)]); + Vec line_2(matrix[ind(2, 0)], matrix[ind(2, 1)], matrix[ind(2, 2)]); + + line_0.normalize(); + line_1.normalize(); + line_2.normalize(); + + // The camera position is at (0,0,0) in the camera CS so it is the + // intersection of the 3 planes. It can be seen as the kernel + // of the 3x4 projection matrix. We calculate it through 4 dimensional + // vectorial product. We go directly into 3D that is to say we directly + // divide the first 3 coordinates by the 4th one. + + // We derive the 4 dimensional vectorial product formula from the + // computation of a 4x4 determinant that is developped according to + // its 4th column. This implies some 3x3 determinants. + const Vec cam_pos = + Vec(det(matrix[ind(0, 1)], matrix[ind(0, 2)], matrix[ind(0, 3)], + matrix[ind(1, 1)], matrix[ind(1, 2)], matrix[ind(1, 3)], + matrix[ind(2, 1)], matrix[ind(2, 2)], matrix[ind(2, 3)]), + + -det(matrix[ind(0, 0)], matrix[ind(0, 2)], matrix[ind(0, 3)], + matrix[ind(1, 0)], matrix[ind(1, 2)], matrix[ind(1, 3)], + matrix[ind(2, 0)], matrix[ind(2, 2)], matrix[ind(2, 3)]), + + det(matrix[ind(0, 0)], matrix[ind(0, 1)], matrix[ind(0, 3)], + matrix[ind(1, 0)], matrix[ind(1, 1)], matrix[ind(1, 3)], + matrix[ind(2, 0)], matrix[ind(2, 1)], matrix[ind(2, 3)])) / + + (-det(matrix[ind(0, 0)], matrix[ind(0, 1)], matrix[ind(0, 2)], + matrix[ind(1, 0)], matrix[ind(1, 1)], matrix[ind(1, 2)], + matrix[ind(2, 0)], matrix[ind(2, 1)], matrix[ind(2, 2)])); + + // We compute the rotation matrix column by column. + + // GL Z axis is front facing. + Vec column_2 = -line_2; + + // X-axis is almost like line_0 but should be orthogonal to the Z axis. + Vec column_0 = ((column_2 ^ line_0) ^ column_2); + column_0.normalize(); + + // Y-axis is almost like line_1 but should be orthogonal to the Z axis. + // Moreover line_1 is downward oriented as the screen CS. + Vec column_1 = -((column_2 ^ line_1) ^ column_2); + column_1.normalize(); + + qreal rot[3][3]; + rot[0][0] = column_0[0]; + rot[1][0] = column_0[1]; + rot[2][0] = column_0[2]; + + rot[0][1] = column_1[0]; + rot[1][1] = column_1[1]; + rot[2][1] = column_1[2]; + + rot[0][2] = column_2[0]; + rot[1][2] = column_2[1]; + rot[2][2] = column_2[2]; + + // We compute the field of view + + // line_1^column_0 -> vector of intersection line between + // y_screen=0 and x_camera=0 plane. + // column_2*(...) -> cos of the angle between Z vector et y_screen=0 plane + // * 2 -> field of view = 2 * half angle + + // We need some intermediate values. + Vec dummy = line_1 ^ column_0; + dummy.normalize(); + qreal fov = acos(column_2 * dummy) * 2.0; + + // We set the camera. + Quaternion q; + q.setFromRotationMatrix(rot); + setOrientation(q); + setPosition(cam_pos); + setFieldOfView(fov); +} + +/* + // persp : projectionMatrix_[0] = f/aspectRatio(); +CGAL_INLINE_FUNCTION +void Camera::setFromProjectionMatrix(const GLdouble* projectionMatrix) +{ + QString message; + if ((fabs(projectionMatrix[1]) > 1E-3) || + (fabs(projectionMatrix[2]) > 1E-3) || + (fabs(projectionMatrix[3]) > 1E-3) || + (fabs(projectionMatrix[4]) > 1E-3) || + (fabs(projectionMatrix[6]) > 1E-3) || + (fabs(projectionMatrix[7]) > 1E-3) || + (fabs(projectionMatrix[8]) > 1E-3) || + (fabs(projectionMatrix[9]) > 1E-3)) + message = "Non null coefficient in projection matrix - Aborting"; + else + if ((fabs(projectionMatrix[11]+1.0) < 1E-5) && (fabs(projectionMatrix[15]) < +1E-5)) + { + if (projectionMatrix[5] < 1E-4) + message="Negative field of view in Camera::setFromProjectionMatrix"; + else + setType(Camera::PERSPECTIVE); + } + else + if ((fabs(projectionMatrix[11]) < 1E-5) && (fabs(projectionMatrix[15]-1.0) < +1E-5)) setType(Camera::ORTHOGRAPHIC); else message = "Unable to determine camera +type in setFromProjectionMatrix - Aborting"; + + if (!message.isEmpty()) + { + qWarning(message); + return; + } + + switch (type()) + { + case Camera::PERSPECTIVE: + { + setFieldOfView(2.0 * atan(1.0/projectionMatrix[5])); + const qreal far = projectionMatrix[14] / (2.0 * (1.0 + projectionMatrix[10])); + const qreal near = (projectionMatrix[10]+1.0) / (projectionMatrix[10]-1.0) * +far; setSceneRadius((far-near)/2.0); setSceneCenter(position() + (near + +sceneRadius())*viewDirection()); break; + } + case Camera::ORTHOGRAPHIC: + { + GLdouble w, h; + getOrthoWidthHeight(w,h); + projectionMatrix_[0] = 1.0/w; + projectionMatrix_[5] = 1.0/h; + projectionMatrix_[10] = -2.0/(ZFar - ZNear); + projectionMatrix_[11] = 0.0; + projectionMatrix_[14] = -(ZFar + ZNear)/(ZFar - ZNear); + projectionMatrix_[15] = 1.0; + // same as glOrtho( -w, w, -h, h, zNear(), zFar() ); + break; + } + } +} +*/ + +///////////////////////// Camera to world transform /////////////////////// + +/*! Same as cameraCoordinatesOf(), but with \c qreal[3] parameters (\p src and + * \p res may be identical pointers). */ +CGAL_INLINE_FUNCTION +void Camera::getCameraCoordinatesOf(const qreal src[3], qreal res[3]) const { + Vec r = cameraCoordinatesOf(Vec(src)); + for (int i = 0; i < 3; ++i) + res[i] = r[i]; +} + +/*! Same as worldCoordinatesOf(), but with \c qreal[3] parameters (\p src and \p + * res may be identical pointers). */ +CGAL_INLINE_FUNCTION +void Camera::getWorldCoordinatesOf(const qreal src[3], qreal res[3]) const { + Vec r = worldCoordinatesOf(Vec(src)); + for (int i = 0; i < 3; ++i) + res[i] = r[i]; +} + +/*! Fills \p viewport with the Camera OpenGL viewport. + +This method is mainly used in conjunction with \c gluProject, which requires +such a viewport. Returned values are (0, screenHeight(), screenWidth(), - +screenHeight()), so that the origin is located in the \e upper left corner of +the window (Qt style coordinate system). */ +CGAL_INLINE_FUNCTION +void Camera::getViewport(GLint viewport[4]) const { + viewport[0] = 0; + viewport[1] = screenHeight(); + viewport[2] = screenWidth(); + viewport[3] = -screenHeight(); +} + +//source code of GluProject and GluUnproject, imported here to avoid the dependency to Glu +CGAL_INLINE_FUNCTION +int project(qreal objx, qreal objy, qreal objz, GLdouble *modelview, + GLdouble *projection, int *viewport, GLdouble*winX, GLdouble *winY,GLdouble *winZ) + { + //Transformation vectors + GLdouble fTempo[8]; + //Modelview transform + fTempo[0]=modelview[0]*objx+modelview[4]*objy+modelview[8]*objz+modelview[12]; //w is always 1 + fTempo[1]=modelview[1]*objx+modelview[5]*objy+modelview[9]*objz+modelview[13]; + fTempo[2]=modelview[2]*objx+modelview[6]*objy+modelview[10]*objz+modelview[14]; + fTempo[3]=modelview[3]*objx+modelview[7]*objy+modelview[11]*objz+modelview[15]; + fTempo[4]=projection[0]*fTempo[0]+projection[4]*fTempo[1]+projection[8]*fTempo[2]+projection[12]*fTempo[3]; + fTempo[5]=projection[1]*fTempo[0]+projection[5]*fTempo[1]+projection[9]*fTempo[2]+projection[13]*fTempo[3]; + fTempo[6]=projection[2]*fTempo[0]+projection[6]*fTempo[1]+projection[10]*fTempo[2]+projection[14]*fTempo[3]; + fTempo[7]=projection[3]*fTempo[0]+projection[7]*fTempo[1]+projection[11]*fTempo[2]+projection[15]*fTempo[3]; + //The result normalizes between -1 and 1 + if(fTempo[7]==0.0) //The w value + return 0; + fTempo[7]=1.0/fTempo[7]; + //Perspective division + fTempo[4]*=fTempo[7]; + fTempo[5]*=fTempo[7]; + fTempo[6]*=fTempo[7]; + //Window coordinates + //Map x, y to range 0-1 + *winX=(fTempo[4]*0.5+0.5)*viewport[2]+viewport[0]; + *winY=(fTempo[5]*0.5+0.5)*viewport[3]+viewport[1]; + //This is only correct when glDepthRange(0.0, 1.0) + *winZ=(1.0+fTempo[6])*0.5; //Between 0 and 1 + return 1; +} + +CGAL_INLINE_FUNCTION +void MultiplyMatrices4by4OpenGL_GLdouble(GLdouble *result, GLdouble *matrix1, GLdouble *matrix2) + { + result[0]=matrix1[0]*matrix2[0]+ + matrix1[4]*matrix2[1]+ + matrix1[8]*matrix2[2]+ + matrix1[12]*matrix2[3]; + result[4]=matrix1[0]*matrix2[4]+ + matrix1[4]*matrix2[5]+ + matrix1[8]*matrix2[6]+ + matrix1[12]*matrix2[7]; + result[8]=matrix1[0]*matrix2[8]+ + matrix1[4]*matrix2[9]+ + matrix1[8]*matrix2[10]+ + matrix1[12]*matrix2[11]; + result[12]=matrix1[0]*matrix2[12]+ + matrix1[4]*matrix2[13]+ + matrix1[8]*matrix2[14]+ + matrix1[12]*matrix2[15]; + result[1]=matrix1[1]*matrix2[0]+ + matrix1[5]*matrix2[1]+ + matrix1[9]*matrix2[2]+ + matrix1[13]*matrix2[3]; + result[5]=matrix1[1]*matrix2[4]+ + matrix1[5]*matrix2[5]+ + matrix1[9]*matrix2[6]+ + matrix1[13]*matrix2[7]; + result[9]=matrix1[1]*matrix2[8]+ + matrix1[5]*matrix2[9]+ + matrix1[9]*matrix2[10]+ + matrix1[13]*matrix2[11]; + result[13]=matrix1[1]*matrix2[12]+ + matrix1[5]*matrix2[13]+ + matrix1[9]*matrix2[14]+ + matrix1[13]*matrix2[15]; + result[2]=matrix1[2]*matrix2[0]+ + matrix1[6]*matrix2[1]+ + matrix1[10]*matrix2[2]+ + matrix1[14]*matrix2[3]; + result[6]=matrix1[2]*matrix2[4]+ + matrix1[6]*matrix2[5]+ + matrix1[10]*matrix2[6]+ + matrix1[14]*matrix2[7]; + result[10]=matrix1[2]*matrix2[8]+ + matrix1[6]*matrix2[9]+ + matrix1[10]*matrix2[10]+ + matrix1[14]*matrix2[11]; + result[14]=matrix1[2]*matrix2[12]+ + matrix1[6]*matrix2[13]+ + matrix1[10]*matrix2[14]+ + matrix1[14]*matrix2[15]; + result[3]=matrix1[3]*matrix2[0]+ + matrix1[7]*matrix2[1]+ + matrix1[11]*matrix2[2]+ + matrix1[15]*matrix2[3]; + result[7]=matrix1[3]*matrix2[4]+ + matrix1[7]*matrix2[5]+ + matrix1[11]*matrix2[6]+ + matrix1[15]*matrix2[7]; + result[11]=matrix1[3]*matrix2[8]+ + matrix1[7]*matrix2[9]+ + matrix1[11]*matrix2[10]+ + matrix1[15]*matrix2[11]; + result[15]=matrix1[3]*matrix2[12]+ + matrix1[7]*matrix2[13]+ + matrix1[11]*matrix2[14]+ + matrix1[15]*matrix2[15]; + } + +CGAL_INLINE_FUNCTION + void MultiplyMatrixByVector4by4OpenGL_GLdouble(GLdouble *resultvector, const GLdouble *matrix, const GLdouble *pvector) + { + resultvector[0]=matrix[0]*pvector[0]+matrix[4]*pvector[1]+matrix[8]*pvector[2]+matrix[12]*pvector[3]; + resultvector[1]=matrix[1]*pvector[0]+matrix[5]*pvector[1]+matrix[9]*pvector[2]+matrix[13]*pvector[3]; + resultvector[2]=matrix[2]*pvector[0]+matrix[6]*pvector[1]+matrix[10]*pvector[2]+matrix[14]*pvector[3]; + resultvector[3]=matrix[3]*pvector[0]+matrix[7]*pvector[1]+matrix[11]*pvector[2]+matrix[15]*pvector[3]; + } + + #define SWAP_ROWS_DOUBLE(a, b) { double *_tmp = a; (a)=(b); (b)=_tmp; } + #define SWAP_ROWS_GLdouble(a, b) { GLdouble *_tmp = a; (a)=(b); (b)=_tmp; } + #define MAT(m,r,c) (m)[(c)*4+(r)] + //This code comes directly from GLU except that it is for GLdouble + CGAL_INLINE_FUNCTION + int glhInvertMatrixf2(GLdouble *m, GLdouble *out) + { + GLdouble wtmp[4][8]; + GLdouble m0, m1, m2, m3, s; + GLdouble *r0, *r1, *r2, *r3; + r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3]; + r0[0] = MAT(m, 0, 0), r0[1] = MAT(m, 0, 1), + r0[2] = MAT(m, 0, 2), r0[3] = MAT(m, 0, 3), + r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0, + r1[0] = MAT(m, 1, 0), r1[1] = MAT(m, 1, 1), + r1[2] = MAT(m, 1, 2), r1[3] = MAT(m, 1, 3), + r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0, + r2[0] = MAT(m, 2, 0), r2[1] = MAT(m, 2, 1), + r2[2] = MAT(m, 2, 2), r2[3] = MAT(m, 2, 3), + r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0, + r3[0] = MAT(m, 3, 0), r3[1] = MAT(m, 3, 1), + r3[2] = MAT(m, 3, 2), r3[3] = MAT(m, 3, 3), + r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0; + /* choose pivot - or die */ + if (fabs(r3[0]) > fabs(r2[0])) + SWAP_ROWS_GLdouble(r3, r2); + if (fabs(r2[0]) > fabs(r1[0])) + SWAP_ROWS_GLdouble(r2, r1); + if (fabs(r1[0]) > fabs(r0[0])) + SWAP_ROWS_GLdouble(r1, r0); + if (0.0 == r0[0]) + return 0; + /* eliminate first variable */ + m1 = r1[0] / r0[0]; + m2 = r2[0] / r0[0]; + m3 = r3[0] / r0[0]; + s = r0[1]; + r1[1] -= m1 * s; + r2[1] -= m2 * s; + r3[1] -= m3 * s; + s = r0[2]; + r1[2] -= m1 * s; + r2[2] -= m2 * s; + r3[2] -= m3 * s; + s = r0[3]; + r1[3] -= m1 * s; + r2[3] -= m2 * s; + r3[3] -= m3 * s; + s = r0[4]; + if (s != 0.0) { + r1[4] -= m1 * s; + r2[4] -= m2 * s; + r3[4] -= m3 * s; + } + s = r0[5]; + if (s != 0.0) { + r1[5] -= m1 * s; + r2[5] -= m2 * s; + r3[5] -= m3 * s; + } + s = r0[6]; + if (s != 0.0) { + r1[6] -= m1 * s; + r2[6] -= m2 * s; + r3[6] -= m3 * s; + } + s = r0[7]; + if (s != 0.0) { + r1[7] -= m1 * s; + r2[7] -= m2 * s; + r3[7] -= m3 * s; + } + /* choose pivot - or die */ + if (fabs(r3[1]) > fabs(r2[1])) + SWAP_ROWS_GLdouble(r3, r2); + if (fabs(r2[1]) > fabs(r1[1])) + SWAP_ROWS_GLdouble(r2, r1); + if (0.0 == r1[1]) + return 0; + /* eliminate second variable */ + m2 = r2[1] / r1[1]; + m3 = r3[1] / r1[1]; + r2[2] -= m2 * r1[2]; + r3[2] -= m3 * r1[2]; + r2[3] -= m2 * r1[3]; + r3[3] -= m3 * r1[3]; + s = r1[4]; + if (0.0 != s) { + r2[4] -= m2 * s; + r3[4] -= m3 * s; + } + s = r1[5]; + if (0.0 != s) { + r2[5] -= m2 * s; + r3[5] -= m3 * s; + } + s = r1[6]; + if (0.0 != s) { + r2[6] -= m2 * s; + r3[6] -= m3 * s; + } + s = r1[7]; + if (0.0 != s) { + r2[7] -= m2 * s; + r3[7] -= m3 * s; + } + /* choose pivot - or die */ + if (fabs(r3[2]) > fabs(r2[2])) + SWAP_ROWS_GLdouble(r3, r2); + if (0.0 == r2[2]) + return 0; + /* eliminate third variable */ + m3 = r3[2] / r2[2]; + r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4], + r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6], r3[7] -= m3 * r2[7]; + /* last check */ + if (0.0 == r3[3]) + return 0; + s = 1.0 / r3[3]; /* now back substitute row 3 */ + r3[4] *= s; + r3[5] *= s; + r3[6] *= s; + r3[7] *= s; + m2 = r2[3]; /* now back substitute row 2 */ + s = 1.0 / r2[2]; + r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2), + r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2); + m1 = r1[3]; + r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1, + r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1; + m0 = r0[3]; + r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0, + r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0; + m1 = r1[2]; /* now back substitute row 1 */ + s = 1.0 / r1[1]; + r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1), + r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1); + m0 = r0[2]; + r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0, + r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0; + m0 = r0[1]; /* now back substitute row 0 */ + s = 1.0 / r0[0]; + r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0), + r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0); + MAT(out, 0, 0) = r0[4]; + MAT(out, 0, 1) = r0[5], MAT(out, 0, 2) = r0[6]; + MAT(out, 0, 3) = r0[7], MAT(out, 1, 0) = r1[4]; + MAT(out, 1, 1) = r1[5], MAT(out, 1, 2) = r1[6]; + MAT(out, 1, 3) = r1[7], MAT(out, 2, 0) = r2[4]; + MAT(out, 2, 1) = r2[5], MAT(out, 2, 2) = r2[6]; + MAT(out, 2, 3) = r2[7], MAT(out, 3, 0) = r3[4]; + MAT(out, 3, 1) = r3[5], MAT(out, 3, 2) = r3[6]; + MAT(out, 3, 3) = r3[7]; + return 1; + } +CGAL_INLINE_FUNCTION +int unProject(GLdouble winx, GLdouble winy, GLdouble winz, GLdouble *modelview, GLdouble *projection, int *viewport, + GLdouble *objX,GLdouble *objY,GLdouble *objZ) + { + //Transformation matrices + GLdouble m[16], A[16]; + GLdouble in[4], out[4]; + //Calculation for inverting a matrix, compute projection x modelview + //and store in A[16] + MultiplyMatrices4by4OpenGL_GLdouble(A, projection, modelview); + //Now compute the inverse of matrix A + if(glhInvertMatrixf2(A, m)==0) + return 0; + //Transformation of normalized coordinates between -1 and 1 + in[0]=(winx-(GLdouble)viewport[0])/(GLdouble)viewport[2]*2.0-1.0; + in[1]=(winy-(GLdouble)viewport[1])/(GLdouble)viewport[3]*2.0-1.0; + in[2]=2.0*winz-1.0; + in[3]=1.0; + //Objects coordinates + MultiplyMatrixByVector4by4OpenGL_GLdouble(out, m, in); + if(out[3]==0.0) + return 0; + out[3]=1.0/out[3]; + *objX=out[0]*out[3]; + *objY=out[1]*out[3]; + *objZ=out[2]*out[3]; + return 1; + } + +/*! Returns the screen projected coordinates of a point \p src defined in the \p frame coordinate + system. + When \p frame in \c NULL (default), \p src is expressed in the world coordinate system. + The x and y coordinates of the returned Vec are expressed in pixel, (0,0) being the \e upper left + corner of the window. The z coordinate ranges between 0.0 (near plane) and 1.0 (excluded, far + plane). See the \c gluProject man page for details. + unprojectedCoordinatesOf() performs the inverse transformation. + See the screenCoordSystem example. + This method only uses the intrinsic Camera parameters (see getModelViewMatrix(), + getProjectionMatrix() and getViewport()) and is completely independent of the OpenGL \c + GL_MODELVIEW, \c GL_PROJECTION and viewport matrices. You can hence define a virtual Camera and use + this method to compute projections out of a classical rendering context. + \attention However, if your Camera is not attached to a CGAL::QGLViewer (used for offscreen computations + for instance), make sure the Camera matrices are updated before calling this method. Call + computeModelViewMatrix() and computeProjectionMatrix() to do so. + If you call this method several times with no change in the matrices, consider precomputing the + projection times modelview matrix to save computation time if required (\c P x \c M in the \c + gluProject man page). + Here is the code corresponding to what this method does (kindly submitted by Robert W. Kuhn) : + \code + Vec project(Vec point) + { + GLint Viewport[4]; + GLdouble Projection[16], Modelview[16]; + GLdouble matrix[16]; + // Precomputation begin + glGetIntegerv(GL_VIEWPORT , Viewport); + glGetDoublev (GL_MODELVIEW_MATRIX , Modelview); + glGetDoublev (GL_PROJECTION_MATRIX, Projection); + for (unsigned short m=0; m<4; ++m) + { + for (unsigned short l=0; l<4; ++l) + { + qreal sum = 0.0; + for (unsigned short k=0; k<4; ++k) + sum += Projection[l+4*k]*Modelview[k+4*m]; + matrix[l+4*m] = sum; + } + } + // Precomputation end + GLdouble v[4], vs[4]; + v[0]=point[0]; v[1]=point[1]; v[2]=point[2]; v[3]=1.0; + vs[0]=matrix[0 ]*v[0] + matrix[4 ]*v[1] + matrix[8 ]*v[2] + matrix[12 ]*v[3]; + vs[1]=matrix[1 ]*v[0] + matrix[5 ]*v[1] + matrix[9 ]*v[2] + matrix[13 ]*v[3]; + vs[2]=matrix[2 ]*v[0] + matrix[6 ]*v[1] + matrix[10]*v[2] + matrix[14 ]*v[3]; + vs[3]=matrix[3 ]*v[0] + matrix[7 ]*v[1] + matrix[11]*v[2] + matrix[15 ]*v[3]; + vs[0] /= vs[3]; + vs[1] /= vs[3]; + vs[2] /= vs[3]; + vs[0] = vs[0] * 0.5 + 0.5; + vs[1] = vs[1] * 0.5 + 0.5; + vs[2] = vs[2] * 0.5 + 0.5; + vs[0] = vs[0] * Viewport[2] + Viewport[0]; + vs[1] = vs[1] * Viewport[3] + Viewport[1]; + return Vec(vs[0], Viewport[3]-vs[1], vs[2]); + } + \endcode + */ +CGAL_INLINE_FUNCTION +Vec Camera::projectedCoordinatesOf(const Vec& src, const Frame* frame) const +{ + GLdouble x = 0.f, y = 0.f, z = 0.f; + static GLint viewport[4]; + getViewport(viewport); + + if (frame) + { + const Vec tmp = frame->inverseCoordinatesOf(src); + project(tmp.x,tmp.y,tmp.z, modelViewMatrix_, projectionMatrix_, viewport, &x,&y,&z); + } + else + project(src.x,src.y,src.z, modelViewMatrix_, projectionMatrix_, viewport, &x,&y,&z); + + return Vec(x,y,z); +} + +/*! Returns the world unprojected coordinates of a point \p src defined in the screen coordinate + system. + The \p src.x and \p src.y input values are expressed in pixels, (0,0) being the \e upper left corner + of the window. \p src.z is a depth value ranging in [0..1[ (respectively corresponding to the near + and far planes). Note that src.z is \e not a linear interpolation between zNear and zFar. + /code + src.z = zFar() / (zFar() - zNear()) * (1.0 - zNear() / z); + /endcode + Where z is the distance from the point you project to the camera, along the viewDirection(). + See the \c gluUnProject man page for details. + The result is expressed in the \p frame coordinate system. When \p frame is \c NULL (default), the + result is expressed in the world coordinates system. The possible \p frame Frame::referenceFrame() + are taken into account. + projectedCoordinatesOf() performs the inverse transformation. + This method only uses the intrinsic Camera parameters (see getModelViewMatrix(), + getProjectionMatrix() and getViewport()) and is completely independent of the OpenGL \c + GL_MODELVIEW, \c GL_PROJECTION and viewport matrices. You can hence define a virtual Camera and use + this method to compute un-projections out of a classical rendering context. + \attention However, if your Camera is not attached to a CGAL::QGLViewer (used for offscreen computations + for instance), make sure the Camera matrices are updated before calling this method (use + computeModelViewMatrix(), computeProjectionMatrix()). See also setScreenWidthAndHeight(). + This method is not computationally optimized. If you call it several times with no change in the + matrices, you should buffer the entire inverse projection matrix (modelview, projection and then + viewport) to speed-up the queries. See the \c gluUnProject man page for details. */ +CGAL_INLINE_FUNCTION +Vec Camera::unprojectedCoordinatesOf(const Vec& src, const Frame* frame) const +{ + GLdouble x = 0.f, y = 0.f, z = 0.f; + static GLint viewport[4]; + getViewport(viewport); + unProject(src.x,src.y,src.z, modelViewMatrix_, projectionMatrix_, viewport, &x,&y,&z); + if (frame) + return frame->coordinatesOf(Vec(x,y,z)); + else + return Vec(x,y,z); +} + +/*! Same as projectedCoordinatesOf(), but with \c qreal parameters (\p src and + * \p res can be identical pointers). */ +CGAL_INLINE_FUNCTION +void Camera::getProjectedCoordinatesOf(const qreal src[3], qreal res[3], + const Frame *frame) const { + Vec r = projectedCoordinatesOf(Vec(src), frame); + for (int i = 0; i < 3; ++i) + res[i] = r[i]; +} + +/*! Same as unprojectedCoordinatesOf(), but with \c qreal parameters (\p src and + * \p res can be identical pointers). */ +CGAL_INLINE_FUNCTION +void Camera::getUnprojectedCoordinatesOf(const qreal src[3], qreal res[3], + const Frame *frame) const { + Vec r = unprojectedCoordinatesOf(Vec(src), frame); + for (int i = 0; i < 3; ++i) + res[i] = r[i]; +} + +///////////////////////////////////// KFI +//////////////////////////////////////////// + +/*! Returns the KeyFrameInterpolator that defines the Camera path number \p i. + +If path \p i is not defined for this index, the method returns a \c NULL +pointer. */ +CGAL_INLINE_FUNCTION +KeyFrameInterpolator *Camera::keyFrameInterpolator(unsigned int i) const { + if (kfi_.contains(i)) + return kfi_[i]; + else + return NULL; +} + +/*! Sets the KeyFrameInterpolator that defines the Camera path of index \p i. + + The previous keyFrameInterpolator() is lost and should be deleted by the + calling method if needed. + + The KeyFrameInterpolator::interpolated() signal of \p kfi probably needs to be + connected to the Camera's associated CGAL::QGLViewer::update() slot, so that when the + Camera position is interpolated using \p kfi, every interpolation step updates + the display: \code myViewer.camera()->deletePath(3); + myViewer.camera()->setKeyFrameInterpolator(3, myKeyFrameInterpolator); + connect(myKeyFrameInterpolator, SIGNAL(interpolated()), myViewer, + SLOT(update()); \endcode + + \note These connections are done automatically when a Camera is attached to a + CGAL::QGLViewer, or when a new KeyFrameInterpolator is defined using the + CGAL::QGLViewer::addKeyFrameKeyboardModifiers() and CGAL::QGLViewer::pathKey() (default is + Alt+F[1-12]). See the keyboard page for details. + */ +CGAL_INLINE_FUNCTION +void Camera::setKeyFrameInterpolator(unsigned int i, + KeyFrameInterpolator *const kfi) { + if (kfi) + kfi_[i] = kfi; + else + kfi_.remove(i); +} + +/*! Adds the current Camera position() and orientation() as a keyFrame to the +path number \p i. + +This method can also be used if you simply want to save a Camera point of view +(a path made of a single keyFrame). Use playPath() to make the Camera play the +keyFrame path (resp. restore the point of view). Use deletePath() to clear the +path. + +The default keyboard shortcut for this method is Alt+F[1-12]. Set +CGAL::QGLViewer::pathKey() and CGAL::QGLViewer::addKeyFrameKeyboardModifiers(). + +If you use directly this method and the keyFrameInterpolator(i) does not exist, +a new one is created. Its KeyFrameInterpolator::interpolated() signal should +then be connected to the CGAL::QGLViewer::update() slot (see +setKeyFrameInterpolator()). */ +CGAL_INLINE_FUNCTION +void Camera::addKeyFrameToPath(unsigned int i) { + if (!kfi_.contains(i)) + setKeyFrameInterpolator(i, new KeyFrameInterpolator(frame())); + + kfi_[i]->addKeyFrame(*(frame())); +} + +/*! Makes the Camera follow the path of keyFrameInterpolator() number \p i. + + If the interpolation is started, it stops it instead. + + This method silently ignores undefined (empty) paths (see + keyFrameInterpolator()). + + The default keyboard shortcut for this method is F[1-12]. Set + CGAL::QGLViewer::pathKey() and CGAL::QGLViewer::playPathKeyboardModifiers(). */ +CGAL_INLINE_FUNCTION +void Camera::playPath(unsigned int i) { + if (kfi_.contains(i)) { + if (kfi_[i]->interpolationIsStarted()) + kfi_[i]->stopInterpolation(); + else + kfi_[i]->startInterpolation(); + } +} + +/*! Resets the path of the keyFrameInterpolator() number \p i. + +If this path is \e not being played (see playPath() and +KeyFrameInterpolator::interpolationIsStarted()), resets it to its starting +position (see KeyFrameInterpolator::resetInterpolation()). If the path is +played, simply stops interpolation. */ +CGAL_INLINE_FUNCTION +void Camera::resetPath(unsigned int i) { + if (kfi_.contains(i)) { + if ((kfi_[i]->interpolationIsStarted())) + kfi_[i]->stopInterpolation(); + else { + kfi_[i]->resetInterpolation(); + kfi_[i]->interpolateAtTime(kfi_[i]->interpolationTime()); + } + } +} + +/*! Deletes the keyFrameInterpolator() of index \p i. + +Disconnect the keyFrameInterpolator() KeyFrameInterpolator::interpolated() +signal before deleting the keyFrameInterpolator() if needed: \code +disconnect(camera()->keyFrameInterpolator(i), SIGNAL(interpolated()), this, +SLOT(update())); camera()->deletePath(i); \endcode */ +CGAL_INLINE_FUNCTION +void Camera::deletePath(unsigned int i) { + if (kfi_.contains(i)) { + kfi_[i]->stopInterpolation(); + delete kfi_[i]; + kfi_.remove(i); + } +} + + +//////////////////////////////////////////////////////////////////////////////// + +/*! Returns an XML \c QDomElement that represents the Camera. + + \p name is the name of the QDomElement tag. \p doc is the \c QDomDocument + factory used to create QDomElement. + + Concatenates the Camera parameters, the ManipulatedCameraFrame::domElement() + and the paths' KeyFrameInterpolator::domElement(). + + Use initFromDOMElement() to restore the Camera state from the resulting \c + QDomElement. + + If you want to save the Camera state in a file, use: + \code + QDomDocument document("myCamera"); + doc.appendChild( myCamera->domElement("Camera", document) ); + + QFile f("myCamera.xml"); + if (f.open(IO_WriteOnly)) + { + QTextStream out(&f); + document.save(out, 2); + } + \endcode + + Note that the CGAL::QGLViewer::camera() is automatically saved by + CGAL::QGLViewer::saveStateToFile() when a CGAL::QGLViewer is closed. Use + CGAL::QGLViewer::restoreStateFromFile() to restore it back. */ +CGAL_INLINE_FUNCTION +QDomElement Camera::domElement(const QString &name, + QDomDocument &document) const { + QDomElement de = document.createElement(name); + QDomElement paramNode = document.createElement("Parameters"); + paramNode.setAttribute("fieldOfView", QString::number(fieldOfView())); + paramNode.setAttribute("zNearCoefficient", + QString::number(zNearCoefficient())); + paramNode.setAttribute("zClippingCoefficient", + QString::number(zClippingCoefficient())); + paramNode.setAttribute("orthoCoef", QString::number(orthoCoef_)); + paramNode.setAttribute("sceneRadius", QString::number(sceneRadius())); + paramNode.appendChild(sceneCenter().domElement("SceneCenter", document)); + + switch (type()) { + case Camera::PERSPECTIVE: + paramNode.setAttribute("Type", "PERSPECTIVE"); + break; + case Camera::ORTHOGRAPHIC: + paramNode.setAttribute("Type", "ORTHOGRAPHIC"); + break; + } + de.appendChild(paramNode); + + QDomElement stereoNode = document.createElement("Stereo"); + stereoNode.setAttribute("IODist", QString::number(IODistance())); + stereoNode.setAttribute("focusDistance", QString::number(focusDistance())); + stereoNode.setAttribute("physScreenWidth", + QString::number(physicalScreenWidth())); + de.appendChild(stereoNode); + + de.appendChild(frame()->domElement("ManipulatedCameraFrame", document)); + + // KeyFrame paths + for (QMap::ConstIterator + it = kfi_.begin(), + end = kfi_.end(); + it != end; ++it) { + QDomElement kfNode = + (it.value())->domElement("KeyFrameInterpolator", document); + kfNode.setAttribute("index", QString::number(it.key())); + de.appendChild(kfNode); + } + + return de; +} + +/*! Restores the Camera state from a \c QDomElement created by domElement(). + + Use the following code to retrieve a Camera state from a file created using + domElement(): \code + // Load DOM from file + QDomDocument document; + QFile f("myCamera.xml"); + if (f.open(IO_ReadOnly)) + { + document.setContent(&f); + f.close(); + } + + // Parse the DOM tree + QDomElement main = document.documentElement(); + myCamera->initFromDOMElement(main); + \endcode + + The frame() pointer is not modified by this method. The frame() state is + however modified. + + \attention The original keyFrameInterpolator() are deleted and should be copied + first if they are shared. */ +CGAL_INLINE_FUNCTION +void Camera::initFromDOMElement(const QDomElement &element) { + QDomElement child = element.firstChild().toElement(); + + QMutableMapIterator it(kfi_); + while (it.hasNext()) { + it.next(); + deletePath(it.key()); + } + + while (!child.isNull()) { + if (child.tagName() == "Parameters") { + // #CONNECTION# Default values set in constructor + setFieldOfView(DomUtils::qrealFromDom(child, "fieldOfView", CGAL_PI / 4.0)); + setZNearCoefficient( + DomUtils::qrealFromDom(child, "zNearCoefficient", 0.005)); + setZClippingCoefficient( + DomUtils::qrealFromDom(child, "zClippingCoefficient", sqrt(3.0))); + orthoCoef_ = + DomUtils::qrealFromDom(child, "orthoCoef", tan(fieldOfView() / 2.0)); + setSceneRadius( + DomUtils::qrealFromDom(child, "sceneRadius", sceneRadius())); + + setType(PERSPECTIVE); + QString type = child.attribute("Type", "PERSPECTIVE"); + if (type == "PERSPECTIVE") + setType(Camera::PERSPECTIVE); + if (type == "ORTHOGRAPHIC") + setType(Camera::ORTHOGRAPHIC); + + QDomElement child2 = child.firstChild().toElement(); + while (!child2.isNull()) { + /* Although the scene does not change when a camera is loaded, restore + the saved center and radius values. Mainly useful when a the viewer is + restored on startup, with possible additional cameras. */ + if (child2.tagName() == "SceneCenter") + setSceneCenter(Vec(child2)); + + child2 = child2.nextSibling().toElement(); + } + } + + if (child.tagName() == "ManipulatedCameraFrame") + frame()->initFromDOMElement(child); + + if (child.tagName() == "Stereo") { + setIODistance(DomUtils::qrealFromDom(child, "IODist", 0.062)); + setFocusDistance( + DomUtils::qrealFromDom(child, "focusDistance", focusDistance())); + setPhysicalScreenWidth( + DomUtils::qrealFromDom(child, "physScreenWidth", 0.5)); + } + + if (child.tagName() == "KeyFrameInterpolator") { + unsigned int index = DomUtils::uintFromDom(child, "index", 0); + setKeyFrameInterpolator(index, new KeyFrameInterpolator(frame())); + if (keyFrameInterpolator(index)) + keyFrameInterpolator(index)->initFromDOMElement(child); + } + + child = child.nextSibling().toElement(); + } +} + +/*! Gives the coefficients of a 3D half-line passing through the Camera eye and + pixel (x,y). + + The origin of the half line (eye position) is stored in \p orig, while \p dir + contains the properly oriented and normalized direction of the half line. + + \p x and \p y are expressed in Qt format (origin in the upper left corner). Use + screenHeight() - y to convert to OpenGL units. + + This method is useful for analytical intersection in a selection method. + + See the select example for an + illustration. */ +CGAL_INLINE_FUNCTION +void Camera::convertClickToLine(const QPoint &pixel, Vec &orig, + Vec &dir) const { + switch (type()) { + case Camera::PERSPECTIVE: + orig = position(); + dir = Vec(((2.0 * pixel.x() / screenWidth()) - 1.0) * + tan(fieldOfView() / 2.0) * aspectRatio(), + ((2.0 * (screenHeight() - pixel.y()) / screenHeight()) - 1.0) * + tan(fieldOfView() / 2.0), + -1.0); + dir = worldCoordinatesOf(dir) - orig; + dir.normalize(); + break; + + case Camera::ORTHOGRAPHIC: { + GLdouble w, h; + getOrthoWidthHeight(w, h); + orig = Vec((2.0 * pixel.x() / screenWidth() - 1.0) * w, + -(2.0 * pixel.y() / screenHeight() - 1.0) * h, 0.0); + orig = worldCoordinatesOf(orig); + dir = viewDirection(); + break; + } + } +} + + +/*! Returns the 6 plane equations of the Camera frustum. + +The six 4-component vectors of \p coef respectively correspond to the left, +right, near, far, top and bottom Camera frustum planes. Each vector holds a +plane equation of the form: \code a*x + b*y + c*z + d = 0 \endcode where \c a, +\c b, \c c and \c d are the 4 components of each vector, in that order. + +See the frustumCulling example for +an application. + +This format is compatible with the \c glClipPlane() function. One camera frustum +plane can hence be applied in an other viewer to visualize the culling results: +\code + // Retrieve plane equations + GLdouble coef[6][4]; + mainViewer->camera()->getFrustumPlanesCoefficients(coef); + + // These two additional clipping planes (which must have been enabled) + // will reproduce the mainViewer's near and far clipping. + glClipPlane(GL_CLIP_PLANE0, coef[2]); + glClipPlane(GL_CLIP_PLANE1, coef[3]); +\endcode */ +CGAL_INLINE_FUNCTION +void Camera::getFrustumPlanesCoefficients(GLdouble coef[6][4]) const { + // Computed once and for all + const Vec pos = position(); + const Vec viewDir = viewDirection(); + const Vec up = upVector(); + const Vec right = rightVector(); + const qreal posViewDir = pos * viewDir; + + static Vec normal[6]; + static GLdouble dist[6]; + + switch (type()) { + case Camera::PERSPECTIVE: { + const qreal hhfov = horizontalFieldOfView() / 2.0; + const qreal chhfov = cos(hhfov); + const qreal shhfov = sin(hhfov); + normal[0] = -shhfov * viewDir; + normal[1] = normal[0] + chhfov * right; + normal[0] = normal[0] - chhfov * right; + + normal[2] = -viewDir; + normal[3] = viewDir; + + const qreal hfov = fieldOfView() / 2.0; + const qreal chfov = cos(hfov); + const qreal shfov = sin(hfov); + normal[4] = -shfov * viewDir; + normal[5] = normal[4] - chfov * up; + normal[4] = normal[4] + chfov * up; + + for (int i = 0; i < 2; ++i) + dist[i] = pos * normal[i]; + for (int j = 4; j < 6; ++j) + dist[j] = pos * normal[j]; + + // Natural equations are: + // dist[0,1,4,5] = pos * normal[0,1,4,5]; + // dist[2] = (pos + zNear() * viewDir) * normal[2]; + // dist[3] = (pos + zFar() * viewDir) * normal[3]; + + // 2 times less computations using expanded/merged equations. Dir vectors + // are normalized. + const qreal posRightCosHH = chhfov * pos * right; + dist[0] = -shhfov * posViewDir; + dist[1] = dist[0] + posRightCosHH; + dist[0] = dist[0] - posRightCosHH; + const qreal posUpCosH = chfov * pos * up; + dist[4] = -shfov * posViewDir; + dist[5] = dist[4] - posUpCosH; + dist[4] = dist[4] + posUpCosH; + + break; + } + case Camera::ORTHOGRAPHIC: + normal[0] = -right; + normal[1] = right; + normal[4] = up; + normal[5] = -up; + + GLdouble hw, hh; + getOrthoWidthHeight(hw, hh); + dist[0] = (pos - hw * right) * normal[0]; + dist[1] = (pos + hw * right) * normal[1]; + dist[4] = (pos + hh * up) * normal[4]; + dist[5] = (pos - hh * up) * normal[5]; + break; + } + + // Front and far planes are identical for both camera types. + normal[2] = -viewDir; + normal[3] = viewDir; + dist[2] = -posViewDir - zNear(); + dist[3] = posViewDir + zFar(); + + for (int i = 0; i < 6; ++i) { + coef[i][0] = GLdouble(normal[i].x); + coef[i][1] = GLdouble(normal[i].y); + coef[i][2] = GLdouble(normal[i].z); + coef[i][3] = dist[i]; + } +} + +CGAL_INLINE_FUNCTION +void Camera::onFrameModified() { + projectionMatrixIsUpToDate_ = false; + modelViewMatrixIsUpToDate_ = false; +} + +CGAL_INLINE_FUNCTION +void Camera::setHorizontalFieldOfView(qreal hfov) { + setFieldOfView(2.0 * atan(tan(hfov / 2.0) / aspectRatio())); +} + +CGAL_INLINE_FUNCTION +qreal Camera::horizontalFieldOfView() const { + return 2.0 * atan(tan(fieldOfView() / 2.0) * aspectRatio()); +} + +CGAL_INLINE_FUNCTION +qreal Camera::physicalDistanceToScreen() const { + return physicalScreenWidth() / 2.0 / tan(horizontalFieldOfView() / 2.0); +} + + +CGAL_INLINE_FUNCTION +void Camera::setFrustum(double frustum[6]) +{ + double l(frustum[0]),r(frustum[1]),t(frustum[2]), + b(frustum[3]),n(frustum[4]),f(frustum[5]); + if(type() == PERSPECTIVE) + { + double A = 2*n/(r-l); + double B = (r+l)/(r-l); + double C = 2*n/(t-b); + double D = (t+b)/(t-b); + double E = -(f+n)/(f-n); + double F = -2*(f*n)/(f-n); + projectionMatrix_[0] = A; projectionMatrix_[4] = 0; projectionMatrix_[8] = B ; projectionMatrix_[12] = 0; + projectionMatrix_[1] = 0; projectionMatrix_[5] = C; projectionMatrix_[9] = D ; projectionMatrix_[13] = 0; + projectionMatrix_[2] = 0; projectionMatrix_[6] = 0; projectionMatrix_[10] = E ; projectionMatrix_[14] = F; + projectionMatrix_[3] =0; projectionMatrix_[7] =0; projectionMatrix_[11] =-1; projectionMatrix_[15] =0; + } + else + { + double A = 2/(r-l); + double B = -(r+l)/(r-l); + double C = 2/(t-b); + double D = -(t+b)/(t-b); + double E = -(f+n)/(f-n); + double F = -2/(f-n); + projectionMatrix_[0] = A; projectionMatrix_[1] = 0; projectionMatrix_[2] = 0 ; projectionMatrix_[3] = 0; + projectionMatrix_[4] = 0; projectionMatrix_[5] = C; projectionMatrix_[6] = 0 ; projectionMatrix_[7] = 0; + projectionMatrix_[8] = 0; projectionMatrix_[9] = 0; projectionMatrix_[10] = F ; projectionMatrix_[11] = 0; + projectionMatrix_[12] = B; projectionMatrix_[13] = D; projectionMatrix_[14] = E; projectionMatrix_[15] = 1; + } + projectionMatrixIsUpToDate_ = true; +} + +CGAL_INLINE_FUNCTION +void Camera::getFrustum(double frustum[6]) +{ + double l,r,t,b,n,f; + if(type() == PERSPECTIVE) + { + n = projectionMatrix_[14]/2*((projectionMatrix_[10]+1)/(projectionMatrix_[10]-1)-1); + f = n*(projectionMatrix_[10]-1)/(projectionMatrix_[10]+1); + l = ((2*n/projectionMatrix_[0])*(projectionMatrix_[8]-1)/(projectionMatrix_[8]+1))/(1-(projectionMatrix_[8]-1)/(projectionMatrix_[8]+1)); + r = 2*n/projectionMatrix_[0]+l; + b=(-2*n/projectionMatrix_[5]*(1-projectionMatrix_[9])/(1+projectionMatrix_[9]))/(1+(1-projectionMatrix_[9])/(1+projectionMatrix_[9])); + t = 2*n/projectionMatrix_[5]+b; + } + else + { + double A(projectionMatrix_[0]),B(projectionMatrix_[12]), + C(projectionMatrix_[5]),D(projectionMatrix_[13]), + E(projectionMatrix_[14]),F(projectionMatrix_[10]); + double B1 = (B+1)/(1-B), D1 = (1-D)/(D+1), + E1=(E+1)/(1-E); + + l = -2*B1/(1+B1*A); + r = 2+A*l; + t = 2*D1/(C*(1+D1)); + b =t -2/C; + n = -2/(F*(1+E1)); + f=n-2/F; + + } + frustum[0] = l; + frustum[1] = r; + frustum[2] = t; + frustum[3] = b; + frustum[4] = n; + frustum[5] = f; +} +}}//end of namespace diff --git a/GraphicsView/include/CGAL/Qt/constraint.h b/GraphicsView/include/CGAL/Qt/constraint.h new file mode 100644 index 00000000000..842ea58efb7 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/constraint.h @@ -0,0 +1,368 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 +#ifndef QGLVIEWER_CONSTRAINT_H +#define QGLVIEWER_CONSTRAINT_H + +#include +#include +#include + +namespace CGAL{ +namespace qglviewer { +class Frame; +class Camera; +/*! \brief An interface class for Frame constraints. + \class Constraint constraint.h CGAL::QGLViewer/constraint.h + + This class defines the interface for the Constraints that can be applied to a + Frame to limit its motion. Use Frame::setConstraint() to associate a + Constraint to a Frame (default is a \c NULL Frame::constraint()). + +

How does it work ?

+ + The Constraint acts as a filter on the translation and rotation Frame + increments. constrainTranslation() and constrainRotation() should be + overloaded to specify the constraint behavior: the desired displacement is + given as a parameter that can optionally be modified. + + Here is how the Frame::translate() and Frame::rotate() methods use the + Constraint: \code Frame::translate(Vec& T) + { + if (constraint()) + constraint()->constrainTranslation(T, this); + t += T; + } + + Frame::rotate(Quaternion& Q) + { + if (constraint()) + constraint()->constrainRotation(Q, this); + q *= Q; + } + \endcode + + The default behavior of constrainTranslation() and constrainRotation() is + empty (meaning no filtering). + + The Frame which uses the Constraint is passed as a parameter to the + constrainTranslation() and constrainRotation() methods, so that they can have + access to its current state (mainly Frame::position() and + Frame::orientation()). It is not \c const for versatility reasons, but + directly modifying it should be avoided. + + \attention Frame::setTranslation(), Frame::setRotation() and similar methods + will actually indeed set the frame position and orientation, without taking + the constraint into account. Use the \e WithConstraint versions of these + methods to enforce the Constraint. + +

Implemented Constraints

+ + Classical axial and plane Constraints are provided for convenience: see the + LocalConstraint, WorldConstraint and CameraConstraint classes' documentations. + + Try the constrainedFrame and + constrainedCamera examples + for an illustration. + +

Creating new Constraints

+ + The implementation of a new Constraint class simply consists in overloading + the filtering methods: \code + // This Constraint enforces that the Frame cannot have a negative z world + coordinate. class myConstraint : public Constraint + { + public: + virtual void constrainTranslation(Vec& t, Frame * const fr) + { + // Express t in the world coordinate system. + const Vec tWorld = fr->inverseTransformOf(t); + if (fr->position().z + tWorld.z < 0.0) // check the new fr z coordinate + t.z = fr->transformOf(-fr->position().z); // t.z is clamped so that + next z position is 0.0 + } + }; + \endcode + + Note that the translation (resp. rotation) parameter passed to + constrainTranslation() (resp. constrainRotation()) is expressed in the \e + local Frame coordinate system. Here, we use the Frame::transformOf() and + Frame::inverseTransformOf() method to convert it to and from the world + coordinate system. + + Combined constraints can easily be achieved by creating a new class that + applies the different constraint filters: \code + myConstraint::constrainTranslation(Vec& v, Frame* const fr) + { + constraint1->constrainTranslation(v, fr); + constraint2->constrainTranslation(v, fr); + // and so on, with possible branches, tests, loops... + } + \endcode + */ +class CGAL_QT_EXPORT Constraint { +public: + /*! Virtual destructor. Empty. */ + virtual ~Constraint() {} + + /*! Filters the translation applied to the \p frame. This default + implementation is empty (no filtering). + + Overload this method in your own Constraint class to define a new translation + constraint. \p frame is the Frame to which is applied the translation. It is + not defined \c const, but you should refrain from directly changing its value + in the constraint. Use its Frame::position() and update the \p translation + accordingly instead. + + \p translation is expressed in local frame coordinate system. Use + Frame::inverseTransformOf() to express it in the world coordinate system if + needed. */ + virtual void constrainTranslation(Vec &translation, Frame *const frame) { + Q_UNUSED(translation); + Q_UNUSED(frame); + } + /*! Filters the rotation applied to the \p frame. This default implementation + is empty (no filtering). + + Overload this method in your own Constraint class to define a new rotation + constraint. See constrainTranslation() for details. + + Use Frame::inverseTransformOf() on the \p rotation Quaternion::axis() to + express \p rotation in the world coordinate system if needed. */ + virtual void constrainRotation(Quaternion &rotation, Frame *const frame) { + Q_UNUSED(rotation); + Q_UNUSED(frame); + } +}; + +/*! + \brief An abstract class for Frame Constraints defined by an axis or a plane. + \class AxisPlaneConstraint constraint.h CGAL::QGLViewer/constraint.h + + AxisPlaneConstraint is an interface for (translation and/or rotation) + Constraint that are defined by a direction. translationConstraintType() and + rotationConstraintType() define how this direction should be interpreted: as + an axis (AxisPlaneConstraint::AXIS) or as a plane normal + (AxisPlaneConstraint::PLANE). See the Type() documentation for details. + + The three implementations of this class: LocalConstraint, WorldConstraint and + CameraConstraint differ by the coordinate system in which this direction is + expressed. + + Different implementations of this class are illustrated in the + contrainedCamera and + constrainedFrame examples. + + \attention When applied, the rotational Constraint may not intuitively follow + the mouse displacement. A solution would be to directly measure the rotation + angle in screen coordinates, but that would imply to know the + CGAL::QGLViewer::camera(), so that we can compute the projected coordinates of the + rotation center (as is done with the CGAL::QGLViewer::SCREEN_ROTATE binding). + However, adding an extra pointer to the CGAL::QGLViewer::camera() in all the + AxisPlaneConstraint derived classes (which the user would have to update in a + multi-viewer application) was judged as an overkill. */ +class CGAL_QT_EXPORT AxisPlaneConstraint : public Constraint { +public: + AxisPlaneConstraint(); + /*! Virtual destructor. Empty. */ + virtual ~AxisPlaneConstraint() {} + + /*! Type lists the different types of translation and rotation constraints + that are available. + + It specifies the meaning of the constraint direction (see + translationConstraintDirection() and rotationConstraintDirection()): as an + axis direction (AxisPlaneConstraint::AXIS) or a plane normal + (AxisPlaneConstraint::PLANE). AxisPlaneConstraint::FREE means no constraint + while AxisPlaneConstraint::FORBIDDEN completely forbids the translation and/or + the rotation. + + See translationConstraintType() and rotationConstraintType(). + + \attention The AxisPlaneConstraint::PLANE Type is not valid for rotational + constraint. + + New derived classes can use their own extended enum for specific constraints: + \code + class MyAxisPlaneConstraint : public AxisPlaneConstraint + { + public: + enum MyType { FREE, AXIS, PLANE, FORBIDDEN, CUSTOM }; + virtual void constrainTranslation(Vec &translation, Frame *const frame) + { + // translationConstraintType() is simply an int. CUSTOM Type is + handled seamlessly. switch (translationConstraintType()) + { + case MyAxisPlaneConstraint::FREE: ... break; + case MyAxisPlaneConstraint::CUSTOM: ... break; + } + }; + + MyAxisPlaneConstraint* c = new MyAxisPlaneConstraint(); + // Note the Type conversion + c->setTranslationConstraintType(AxisPlaneConstraint::Type(MyAxisPlaneConstraint::CUSTOM)); + }; + \endcode */ + enum Type { FREE, AXIS, PLANE, FORBIDDEN }; + + /*! @name Translation constraint */ + //@{ + /*! Overloading of Constraint::constrainTranslation(). Empty */ + virtual void constrainTranslation(Vec &translation, Frame *const frame) { + Q_UNUSED(translation); + Q_UNUSED(frame); + }; + + void setTranslationConstraint(Type type, const Vec &direction); + /*! Sets the Type() of the translationConstraintType(). Default is + * AxisPlaneConstraint::FREE. */ + void setTranslationConstraintType(Type type) { + translationConstraintType_ = type; + }; + void setTranslationConstraintDirection(const Vec &direction); + + /*! Returns the translation constraint Type(). + + Depending on this value, the Frame will freely translate + (AxisPlaneConstraint::FREE), will only be able to translate along an axis + direction (AxisPlaneConstraint::AXIS), will be forced to stay into a plane + (AxisPlaneConstraint::PLANE) or will not able to translate at all + (AxisPlaneConstraint::FORBIDDEN). + + Use Frame::setPosition() to define the position of the constrained Frame + before it gets constrained. */ + Type translationConstraintType() const { return translationConstraintType_; }; + /*! Returns the direction used by the translation constraint. + + It represents the axis direction (AxisPlaneConstraint::AXIS) or the plane + normal (AxisPlaneConstraint::PLANE) depending on the + translationConstraintType(). It is undefined for AxisPlaneConstraint::FREE or + AxisPlaneConstraint::FORBIDDEN. + + The AxisPlaneConstraint derived classes express this direction in different + coordinate system (camera for CameraConstraint, local for LocalConstraint, and + world for WorldConstraint). This value can be modified with + setTranslationConstraintDirection(). */ + Vec translationConstraintDirection() const { + return translationConstraintDir_; + }; + //@} + + /*! @name Rotation constraint */ + //@{ + /*! Overloading of Constraint::constrainRotation(). Empty. */ + virtual void constrainRotation(Quaternion &rotation, Frame *const frame) { + Q_UNUSED(rotation); + Q_UNUSED(frame); + }; + + void setRotationConstraint(Type type, const Vec &direction); + void setRotationConstraintType(Type type); + void setRotationConstraintDirection(const Vec &direction); + + /*! Returns the rotation constraint Type(). */ + Type rotationConstraintType() const { return rotationConstraintType_; }; + /*! Returns the axis direction used by the rotation constraint. + + This direction is defined only when rotationConstraintType() is + AxisPlaneConstraint::AXIS. + + The AxisPlaneConstraint derived classes express this direction in different + coordinate system (camera for CameraConstraint, local for LocalConstraint, and + world for WorldConstraint). This value can be modified with + setRotationConstraintDirection(). */ + Vec rotationConstraintDirection() const { return rotationConstraintDir_; }; + //@} + +private: + // int and not Type to allow for overloading and new types definition. + Type translationConstraintType_; + Type rotationConstraintType_; + + Vec translationConstraintDir_; + Vec rotationConstraintDir_; +}; + +/*! \brief An AxisPlaneConstraint defined in the Frame local coordinate system. + \class LocalConstraint constraint.h CGAL::QGLViewer/constraint.h + + The translationConstraintDirection() and rotationConstraintDirection() are + expressed in the Frame local coordinate system (see Frame::referenceFrame()). + + See the constrainedFrame + example for an illustration. */ +class CGAL_QT_EXPORT LocalConstraint : public AxisPlaneConstraint { +public: + /*! Virtual destructor. Empty. */ + virtual ~LocalConstraint(){}; + + virtual void constrainTranslation(Vec &translation, Frame *const frame); + virtual void constrainRotation(Quaternion &rotation, Frame *const frame); +}; + +/*! \brief An AxisPlaneConstraint defined in the world coordinate system. + \class WorldConstraint constraint.h CGAL::QGLViewer/constraint.h + + The translationConstraintDirection() and rotationConstraintDirection() are + expressed in world coordinate system. + + See the constrainedFrame and + multiView examples for an + illustration. */ +class CGAL_QT_EXPORT WorldConstraint : public AxisPlaneConstraint { +public: + /*! Virtual destructor. Empty. */ + virtual ~WorldConstraint(){}; + + virtual void constrainTranslation(Vec &translation, Frame *const frame); + virtual void constrainRotation(Quaternion &rotation, Frame *const frame); +}; + +/*! \brief An AxisPlaneConstraint defined in the camera coordinate system. + \class CameraConstraint constraint.h CGAL::QGLViewer/constraint.h + + The translationConstraintDirection() and rotationConstraintDirection() are + expressed in the associated camera() coordinate system. + + See the constrainedFrame and + constrainedCamera examples + for an illustration. */ +class CGAL_QT_EXPORT CameraConstraint : public AxisPlaneConstraint { +public: + explicit CameraConstraint(const Camera *const camera); + /*! Virtual destructor. Empty. */ + virtual ~CameraConstraint(){} + + virtual void constrainTranslation(Vec &translation, Frame *const frame); + virtual void constrainRotation(Quaternion &rotation, Frame *const frame); + + /*! Returns the associated Camera. Set using the CameraConstraint constructor. + */ + const Camera *camera() const { return camera_; } + +private: + const Camera *const camera_; +}; + +}} // namespace CGAL::qglviewer + +#ifdef CGAL_HEADER_ONLY +//#include +#endif // CGAL_HEADER_ONLY +#endif // QGLVIEWER_CONSTRAINT_H diff --git a/GraphicsView/include/CGAL/Qt/constraint_impl.h b/GraphicsView/include/CGAL/Qt/constraint_impl.h new file mode 100644 index 00000000000..c37fca4a729 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/constraint_impl.h @@ -0,0 +1,302 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 + +#ifdef CGAL_HEADER_ONLY +#define CGAL_INLINE_FUNCTION inline + +#include + +#else +#define CGAL_INLINE_FUNCTION +#endif + +#include +#include +#include + +namespace CGAL{ +namespace qglviewer{ + + +//////////////////////////////////////////////////////////////////////////////// +// Constraint // +//////////////////////////////////////////////////////////////////////////////// + +/*! Default constructor. + +translationConstraintType() and rotationConstraintType() are set to +AxisPlaneConstraint::FREE. translationConstraintDirection() and +rotationConstraintDirection() are set to (0,0,0). */ +CGAL_INLINE_FUNCTION +AxisPlaneConstraint::AxisPlaneConstraint() + : translationConstraintType_(FREE), rotationConstraintType_(FREE) { + // Do not use set since setRotationConstraintType needs a read. +} + +/*! Simply calls setTranslationConstraintType() and + * setTranslationConstraintDirection(). */ +CGAL_INLINE_FUNCTION +void AxisPlaneConstraint::setTranslationConstraint(Type type, + const Vec &direction) { + setTranslationConstraintType(type); + setTranslationConstraintDirection(direction); +} + +/*! Defines the translationConstraintDirection(). The coordinate system where \p + * direction is expressed depends on your class implementation. */ +CGAL_INLINE_FUNCTION +void AxisPlaneConstraint::setTranslationConstraintDirection( + const Vec &direction) { + if ((translationConstraintType() != AxisPlaneConstraint::FREE) && + (translationConstraintType() != AxisPlaneConstraint::FORBIDDEN)) { + const qreal norm = direction.norm(); + if (norm < 1E-8) { + qWarning("AxisPlaneConstraint::setTranslationConstraintDir: null vector " + "for translation constraint"); + translationConstraintType_ = AxisPlaneConstraint::FREE; + } else + translationConstraintDir_ = direction / norm; + } +} + +/*! Simply calls setRotationConstraintType() and + * setRotationConstraintDirection(). */ +CGAL_INLINE_FUNCTION +void AxisPlaneConstraint::setRotationConstraint(Type type, + const Vec &direction) { + setRotationConstraintType(type); + setRotationConstraintDirection(direction); +} + +/*! Defines the rotationConstraintDirection(). The coordinate system where \p + * direction is expressed depends on your class implementation. */ +CGAL_INLINE_FUNCTION +void AxisPlaneConstraint::setRotationConstraintDirection(const Vec &direction) { + if ((rotationConstraintType() != AxisPlaneConstraint::FREE) && + (rotationConstraintType() != AxisPlaneConstraint::FORBIDDEN)) { + const qreal norm = direction.norm(); + if (norm < 1E-8) { + qWarning("AxisPlaneConstraint::setRotationConstraintDir: null vector for " + "rotation constraint"); + rotationConstraintType_ = AxisPlaneConstraint::FREE; + } else + rotationConstraintDir_ = direction / norm; + } +} + +/*! Set the Type() of the rotationConstraintType(). Default is + AxisPlaneConstraint::FREE. + + Depending on this value, the Frame will freely rotate + (AxisPlaneConstraint::FREE), will only be able to rotate around an axis + (AxisPlaneConstraint::AXIS), or will not able to rotate at all + (AxisPlaneConstraint::FORBIDDEN). + + Use Frame::setOrientation() to define the orientation of the constrained Frame + before it gets constrained. + + \attention An AxisPlaneConstraint::PLANE Type() is not meaningful for + rotational constraints and will be ignored. */ +CGAL_INLINE_FUNCTION +void AxisPlaneConstraint::setRotationConstraintType(Type type) { + if (rotationConstraintType() == AxisPlaneConstraint::PLANE) { + qWarning("AxisPlaneConstraint::setRotationConstraintType: the PLANE type " + "cannot be used for a rotation constraints"); + return; + } + + rotationConstraintType_ = type; +} + +//////////////////////////////////////////////////////////////////////////////// +// LocalConstraint // +//////////////////////////////////////////////////////////////////////////////// + +/*! Depending on translationConstraintType(), constrain \p translation to be + along an axis or limited to a plane defined in the Frame local coordinate + system by translationConstraintDirection(). */ +CGAL_INLINE_FUNCTION +void LocalConstraint::constrainTranslation(Vec &translation, + Frame *const frame) { + Vec proj; + switch (translationConstraintType()) { + case AxisPlaneConstraint::FREE: + break; + case AxisPlaneConstraint::PLANE: + proj = frame->rotation().rotate(translationConstraintDirection()); + translation.projectOnPlane(proj); + break; + case AxisPlaneConstraint::AXIS: + proj = frame->rotation().rotate(translationConstraintDirection()); + translation.projectOnAxis(proj); + break; + case AxisPlaneConstraint::FORBIDDEN: + translation = Vec(0.0, 0.0, 0.0); + break; + } +} + +/*! When rotationConstraintType() is AxisPlaneConstraint::AXIS, constrain \p + rotation to be a rotation around an axis whose direction is defined in the + Frame local coordinate system by rotationConstraintDirection(). */ +CGAL_INLINE_FUNCTION +void LocalConstraint::constrainRotation(Quaternion &rotation, Frame *const) { + switch (rotationConstraintType()) { + case AxisPlaneConstraint::FREE: + break; + case AxisPlaneConstraint::PLANE: + break; + case AxisPlaneConstraint::AXIS: { + Vec axis = rotationConstraintDirection(); + Vec quat = Vec(rotation[0], rotation[1], rotation[2]); + quat.projectOnAxis(axis); + rotation = Quaternion(quat, 2.0 * acos(rotation[3])); + } break; + case AxisPlaneConstraint::FORBIDDEN: + rotation = Quaternion(); // identity + break; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// WorldConstraint // +//////////////////////////////////////////////////////////////////////////////// + +/*! Depending on translationConstraintType(), constrain \p translation to be + along an axis or limited to a plane defined in the world coordinate system by + translationConstraintDirection(). */ +CGAL_INLINE_FUNCTION +void WorldConstraint::constrainTranslation(Vec &translation, + Frame *const frame) { + Vec proj; + switch (translationConstraintType()) { + case AxisPlaneConstraint::FREE: + break; + case AxisPlaneConstraint::PLANE: + if (frame->referenceFrame()) { + proj = frame->referenceFrame()->transformOf( + translationConstraintDirection()); + translation.projectOnPlane(proj); + } else + translation.projectOnPlane(translationConstraintDirection()); + break; + case AxisPlaneConstraint::AXIS: + if (frame->referenceFrame()) { + proj = frame->referenceFrame()->transformOf( + translationConstraintDirection()); + translation.projectOnAxis(proj); + } else + translation.projectOnAxis(translationConstraintDirection()); + break; + case AxisPlaneConstraint::FORBIDDEN: + translation = Vec(0.0, 0.0, 0.0); + break; + } +} + +/*! When rotationConstraintType() is AxisPlaneConstraint::AXIS, constrain \p + rotation to be a rotation around an axis whose direction is defined in the + world coordinate system by rotationConstraintDirection(). */ +CGAL_INLINE_FUNCTION +void WorldConstraint::constrainRotation(Quaternion &rotation, + Frame *const frame) { + switch (rotationConstraintType()) { + case AxisPlaneConstraint::FREE: + break; + case AxisPlaneConstraint::PLANE: + break; + case AxisPlaneConstraint::AXIS: { + Vec quat(rotation[0], rotation[1], rotation[2]); + Vec axis = frame->transformOf(rotationConstraintDirection()); + quat.projectOnAxis(axis); + rotation = Quaternion(quat, 2.0 * acos(rotation[3])); + break; + } + case AxisPlaneConstraint::FORBIDDEN: + rotation = Quaternion(); // identity + break; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// CameraConstraint // +//////////////////////////////////////////////////////////////////////////////// + +/*! Creates a CameraConstraint, whose constrained directions are defined in the + \p camera coordinate system. */ +CGAL_INLINE_FUNCTION +CameraConstraint::CameraConstraint(const Camera *const camera) + : AxisPlaneConstraint(), camera_(camera) {} + +/*! Depending on translationConstraintType(), constrain \p translation to be + along an axis or limited to a plane defined in the camera() coordinate system + by translationConstraintDirection(). */ +CGAL_INLINE_FUNCTION +void CameraConstraint::constrainTranslation(Vec &translation, + Frame *const frame) { + Vec proj; + switch (translationConstraintType()) { + case AxisPlaneConstraint::FREE: + break; + case AxisPlaneConstraint::PLANE: + proj = + camera()->frame()->inverseTransformOf(translationConstraintDirection()); + if (frame->referenceFrame()) + proj = frame->referenceFrame()->transformOf(proj); + translation.projectOnPlane(proj); + break; + case AxisPlaneConstraint::AXIS: + proj = + camera()->frame()->inverseTransformOf(translationConstraintDirection()); + if (frame->referenceFrame()) + proj = frame->referenceFrame()->transformOf(proj); + translation.projectOnAxis(proj); + break; + case AxisPlaneConstraint::FORBIDDEN: + translation = Vec(0.0, 0.0, 0.0); + break; + } +} + +/*! When rotationConstraintType() is AxisPlaneConstraint::AXIS, constrain \p + rotation to be a rotation around an axis whose direction is defined in the + camera() coordinate system by rotationConstraintDirection(). */ +CGAL_INLINE_FUNCTION +void CameraConstraint::constrainRotation(Quaternion &rotation, + Frame *const frame) { + switch (rotationConstraintType()) { + case AxisPlaneConstraint::FREE: + break; + case AxisPlaneConstraint::PLANE: + break; + case AxisPlaneConstraint::AXIS: { + Vec axis = frame->transformOf( + camera()->frame()->inverseTransformOf(rotationConstraintDirection())); + Vec quat = Vec(rotation[0], rotation[1], rotation[2]); + quat.projectOnAxis(axis); + rotation = Quaternion(quat, 2.0 * acos(rotation[3])); + } break; + case AxisPlaneConstraint::FORBIDDEN: + rotation = Quaternion(); // identity + break; + } +} + +}}//end namespace diff --git a/GraphicsView/include/CGAL/Qt/domUtils.h b/GraphicsView/include/CGAL/Qt/domUtils.h new file mode 100644 index 00000000000..466e6509bbe --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/domUtils.h @@ -0,0 +1,191 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 +#ifndef QGLVIEWER_DOMUTILS_H +#define QGLVIEWER_DOMUTILS_H +#include +#include +#include +#include +#include + +#include + +#ifndef DOXYGEN + +// QDomElement loading with syntax checking. +class DomUtils { +private: + static void warning(const QString &message) { + qWarning("%s", message.toLatin1().constData()); + } + +public: + static qreal qrealFromDom(const QDomElement &e, const QString &attribute, + qreal defValue) { + qreal value = defValue; + if (e.hasAttribute(attribute)) { + const QString s = e.attribute(attribute); + bool ok; + value = s.toDouble(&ok); + if (!ok) { + warning(QString("'%1' is not a valid qreal syntax for attribute \"%2\" " + "in initialization of \"%3\". Setting value to %4.") + .arg(s) + .arg(attribute) + .arg(e.tagName()) + .arg(QString::number(defValue))); + value = defValue; + } + } else { + warning(QString("\"%1\" attribute missing in initialization of \"%2\". " + "Setting value to %3.") + .arg(attribute) + .arg(e.tagName()) + .arg(QString::number(value))); + } + +#if defined(isnan) + // The "isnan" method may not be available on all platforms. + // Find its equivalent or simply remove these two lines + if (isnan(value)) + warning( + QString( + "Warning, attribute \"%1\" initialized to Not a Number in \"%2\"") + .arg(attribute) + .arg(e.tagName())); +#endif + + return value; + } + + static int intFromDom(const QDomElement &e, const QString &attribute, + int defValue) { + int value = defValue; + if (e.hasAttribute(attribute)) { + const QString s = e.attribute(attribute); + bool ok; + value = s.toInt(&ok); + if (!ok) { + warning( + QString("'%1' is not a valid integer syntax for attribute \"%2\" " + "in initialization of \"%3\". Setting value to %4.") + .arg(s) + .arg(attribute) + .arg(e.tagName()) + .arg(QString::number(defValue))); + value = defValue; + } + } else { + warning(QString("\"%1\" attribute missing in initialization of \"%2\". " + "Setting value to %3.") + .arg(attribute) + .arg(e.tagName()) + .arg(QString::number(value))); + } + + return value; + } + + static unsigned int uintFromDom(const QDomElement &e, + const QString &attribute, + unsigned int defValue) { + unsigned int value = defValue; + if (e.hasAttribute(attribute)) { + const QString s = e.attribute(attribute); + bool ok; + value = s.toUInt(&ok); + if (!ok) { + warning( + QString("'%1' is not a valid unsigned integer syntax for attribute " + "\"%2\" in initialization of \"%3\". Setting value to %4.") + .arg(s) + .arg(attribute) + .arg(e.tagName()) + .arg(QString::number(defValue))); + value = defValue; + } + } else { + warning(QString("\"%1\" attribute missing in initialization of \"%2\". " + "Setting value to %3.") + .arg(attribute) + .arg(e.tagName()) + .arg(QString::number(value))); + } + + return value; + } + + static bool boolFromDom(const QDomElement &e, const QString &attribute, + bool defValue) { + bool value = defValue; + if (e.hasAttribute(attribute)) { + const QString s = e.attribute(attribute); + if (s.toLower() == QString("true")) + value = true; + else if (s.toLower() == QString("false")) + value = false; + else { + warning( + QString("'%1' is not a valid boolean syntax for attribute \"%2\" " + "in initialization of \"%3\". Setting value to %4.") + .arg(s) + .arg(attribute) + .arg(e.tagName()) + .arg(defValue ? "true" : "false")); + } + } else { + warning(QString("\"%1\" attribute missing in initialization of \"%2\". " + "Setting value to %3.") + .arg(attribute) + .arg(e.tagName()) + .arg(value ? "true" : "false")); + } + + return value; + } + + static void setBoolAttribute(QDomElement &element, const QString &attribute, + bool value) { + element.setAttribute(attribute, (value ? "true" : "false")); + } + + static QDomElement QColorDomElement(const QColor &color, const QString &name, + QDomDocument &doc) { + QDomElement de = doc.createElement(name); + de.setAttribute("red", QString::number(color.red())); + de.setAttribute("green", QString::number(color.green())); + de.setAttribute("blue", QString::number(color.blue())); + return de; + } + + static QColor QColorFromDom(const QDomElement &e) { + int color[3]; + QStringList attribute; + attribute << "red" + << "green" + << "blue"; + for (int i = 0; i < attribute.count(); ++i) + color[i] = DomUtils::intFromDom(e, attribute[i], 0); + return QColor(color[0], color[1], color[2]); + } +}; + +#endif // DOXYGEN +#endif //QGLVIEWER_DOMUTILS_H diff --git a/GraphicsView/include/CGAL/Qt/frame.h b/GraphicsView/include/CGAL/Qt/frame.h new file mode 100644 index 00000000000..bfc4e28538f --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/frame.h @@ -0,0 +1,463 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 +#ifndef QGLVIEWER_FRAME_H +#define QGLVIEWER_FRAME_H + +#include +#include +#include +#include +#include + +namespace CGAL{ +namespace qglviewer { +class Constraint; + +/*! \brief The Frame class represents a coordinate system, defined by a position + and an orientation. \class Frame frame.h CGAL::QGLViewer/frame.h + + A Frame is a 3D coordinate system, represented by a position() and an + orientation(). The order of these transformations is important: the Frame is + first translated \e and \e then rotated around the new translated origin. + + A Frame is useful to define the position and orientation of a 3D rigid object, + using its matrix() method, as shown below: \code + // Builds a Frame at position (0.5,0,0) and oriented such that its Y axis is + along the (1,1,1) + // direction. One could also have used setPosition() and setOrientation(). + Frame fr(Vec(0.5,0,0), Quaternion(Vec(0,1,0), Vec(1,1,1))); + glPushMatrix(); + glMultMatrixd(fr.matrix()); + // Draw your object here, in the local fr coordinate system. + glPopMatrix(); + \endcode + + Many functions are provided to transform a 3D point from one coordinate system + (Frame) to an other: see coordinatesOf(), inverseCoordinatesOf(), + coordinatesOfIn(), coordinatesOfFrom()... + + You may also want to transform a 3D vector (such as a normal), which + corresponds to applying only the rotational part of the frame transformation: + see transformOf() and inverseTransformOf(). See the frameTransform example for an + illustration. + + The translation() and the rotation() that are encapsulated in a Frame can also + be used to represent a \e rigid \e transformation of space. Such a + transformation can also be interpreted as a change of coordinate system, and + the coordinate system conversion functions actually allow you to use a Frame + as a rigid transformation. Use inverseCoordinatesOf() (resp. coordinatesOf()) + to apply the transformation (resp. its inverse). Note the inversion. + +

Hierarchy of Frames

+ + The position and the orientation of a Frame are actually defined with respect + to a referenceFrame(). The default referenceFrame() is the world coordinate + system (represented by a \c NULL referenceFrame()). If you setReferenceFrame() + to a different Frame, you must then differentiate: + + \arg the \e local translation() and rotation(), defined with respect to the + referenceFrame(), + + \arg the \e global position() and orientation(), always defined with respect + to the world coordinate system. + + A Frame is actually defined by its translation() with respect to its + referenceFrame(), and then by a rotation() of the coordinate system around the + new translated origin. + + This terminology for \e local (translation() and rotation()) and \e global + (position() and orientation()) definitions is used in all the methods' names + and should be sufficient to prevent ambiguities. These notions are obviously + identical when the referenceFrame() is \c NULL, i.e. when the Frame is defined + in the world coordinate system (the one you are in at the beginning of the + CGAL::QGLViewer::draw() method, see the introduction + page). + + Frames can hence easily be organized in a tree hierarchy, which root is the + world coordinate system. A loop in the hierarchy would result in an + inconsistent (multiple) Frame definition. + settingAsReferenceFrameWillCreateALoop() checks this and prevents + setReferenceFrame() from creating such a loop. + + This frame hierarchy is used in methods like coordinatesOfIn(), + coordinatesOfFrom()... which allow coordinates (or vector) conversions from a + Frame to any other one (including the world coordinate system). + + However, one must note that this hierarchical representation is internal to + the Frame classes. When the Frames represent OpenGL coordinates system, one + should map this hierarchical representation to the OpenGL GL_MODELVIEW matrix + stack. See the matrix() documentation for details. + +

Constraints

+ + An interesting feature of Frames is that their displacements can be + constrained. When a Constraint is attached to a Frame, it filters the input of + translate() and rotate(), and only the resulting filtered motion is applied to + the Frame. The default constraint() is \c NULL resulting in no filtering. Use + setConstraint() to attach a Constraint to a frame. + + Constraints are especially usefull for the ManipulatedFrame instances, in + order to forbid some mouse motions. See the constrainedFrame, constrainedCamera and luxo examples for an illustration. + + Classical constraints are provided for convenience (see LocalConstraint, + WorldConstraint and CameraConstraint) and new constraints can very easily be + implemented. + +

Derived classes

+ + The ManipulatedFrame class inherits Frame and implements a mouse motion + convertion, so that a Frame (and hence an object) can be manipulated in the + scene with the mouse. + + \nosubgrouping */ +class CGAL_QT_EXPORT Frame : public QObject { + Q_OBJECT + +public: + Frame(); + + /*! Virtual destructor. Empty. */ + virtual ~Frame() {} + + Frame(const Frame &frame); + Frame &operator=(const Frame &frame); + +Q_SIGNALS: + /*! This signal is emitted whenever the position() or the orientation() of the + Frame is modified. + + Connect this signal to any object that must be notified: + \code + QObject::connect(myFrame, SIGNAL(modified()), myObject, SLOT(update())); + \endcode + Use the CGAL::QGLViewer::QGLViewerPool() to connect the signal to all the viewers. + + \note If your Frame is part of a Frame hierarchy (see referenceFrame()), a + modification of one of the parents of this Frame will \e not emit this signal. + Use code like this to change this behavior (you can do this recursively for + all the referenceFrame() until the \c NULL world root frame is encountered): + \code + // Emits the Frame modified() signal when its referenceFrame() is modified(). + connect(myFrame->referenceFrame(), SIGNAL(modified()), myFrame, + SIGNAL(modified())); \endcode + + \attention Connecting this signal to a QOpenGLWidget::update() slot (or a + method that calls it) will prevent you from modifying the Frame \e inside your + CGAL::QGLViewer::draw() method as it would result in an infinite loop. However, + CGAL::QGLViewer::draw() should not modify the scene. + + \note Note that this signal might be emitted even if the Frame is not actually + modified, for instance after a translate(Vec(0,0,0)) or a + setPosition(position()). */ + void modified(); + + /*! This signal is emitted when the Frame is interpolated by a + KeyFrameInterpolator. + + See the KeyFrameInterpolator documentation for details. + + If a KeyFrameInterpolator is used to successively interpolate several Frames + in your scene, connect the KeyFrameInterpolator::interpolated() signal instead + (identical, but independent of the interpolated Frame). */ + void interpolated(); + +public: + /*! @name World coordinates position and orientation */ + //@{ + Frame(const Vec &position, const Quaternion &orientation); + + void setPosition(const Vec &position); + void setPosition(qreal x, qreal y, qreal z); + void setPositionWithConstraint(Vec &position); + + void setOrientation(const Quaternion &orientation); + void setOrientation(qreal q0, qreal q1, qreal q2, qreal q3); + void setOrientationWithConstraint(Quaternion &orientation); + + void setPositionAndOrientation(const Vec &position, + const Quaternion &orientation); + void setPositionAndOrientationWithConstraint(Vec &position, + Quaternion &orientation); + + Vec position() const; + Quaternion orientation() const; + + void getPosition(qreal &x, qreal &y, qreal &z) const; + void getOrientation(qreal &q0, qreal &q1, qreal &q2, qreal &q3) const; + //@} + +public: + /*! @name Local translation and rotation w/r reference Frame */ + //@{ + /*! Sets the translation() of the frame, locally defined with respect to the + referenceFrame(). Emits the modified() signal. + + Use setPosition() to define the world coordinates position(). Use + setTranslationWithConstraint() to take into account the potential constraint() + of the Frame. */ + void setTranslation(const Vec &translation) { + t_ = translation; + Q_EMIT modified(); + } + void setTranslation(qreal x, qreal y, qreal z); + void setTranslationWithConstraint(Vec &translation); + + /*! Set the current rotation Quaternion. See rotation() and the different + Quaternion constructors. Emits the modified() signal. See also + setTranslation() and setRotationWithConstraint(). */ + + /*! Sets the rotation() of the Frame, locally defined with respect to the + referenceFrame(). Emits the modified() signal. + + Use setOrientation() to define the world coordinates orientation(). The + potential constraint() of the Frame is not taken into account, use + setRotationWithConstraint() instead. */ + void setRotation(const Quaternion &rotation) { + q_ = rotation; + Q_EMIT modified(); + } + void setRotation(qreal q0, qreal q1, qreal q2, qreal q3); + void setRotationWithConstraint(Quaternion &rotation); + + void setTranslationAndRotation(const Vec &translation, + const Quaternion &rotation); + void setTranslationAndRotationWithConstraint(Vec &translation, + Quaternion &rotation); + + /*! Returns the Frame translation, defined with respect to the + referenceFrame(). + + Use position() to get the result in the world coordinates. These two values + are identical when the referenceFrame() is \c NULL (default). + + See also setTranslation() and setTranslationWithConstraint(). */ + Vec translation() const { return t_; } + /*! Returns the Frame rotation, defined with respect to the referenceFrame(). + + Use orientation() to get the result in the world coordinates. These two values + are identical when the referenceFrame() is \c NULL (default). + + See also setRotation() and setRotationWithConstraint(). */ + + /*! Returns the current Quaternion orientation. See setRotation(). */ + Quaternion rotation() const { return q_; } + + void getTranslation(qreal &x, qreal &y, qreal &z) const; + void getRotation(qreal &q0, qreal &q1, qreal &q2, qreal &q3) const; + //@} + +public: + /*! @name Frame hierarchy */ + //@{ + /*! Returns the reference Frame, in which coordinates system the Frame is + defined. + + The translation() and rotation() of the Frame are defined with respect to the + referenceFrame() coordinate system. A \c NULL referenceFrame() (default value) + means that the Frame is defined in the world coordinate system. + + Use position() and orientation() to recursively convert values along the + referenceFrame() chain and to get values expressed in the world coordinate + system. The values match when the referenceFrame() is \c NULL. + + Use setReferenceFrame() to set this value and create a Frame hierarchy. + Convenient functions allow you to convert 3D coordinates from one Frame to an + other: see coordinatesOf(), localCoordinatesOf(), coordinatesOfIn() and their + inverse functions. + + Vectors can also be converted using transformOf(), transformOfIn, + localTransformOf() and their inverse functions. */ + const Frame *referenceFrame() const { return referenceFrame_; } + void setReferenceFrame(const Frame *const refFrame); + bool settingAsReferenceFrameWillCreateALoop(const Frame *const frame); + //@} + + /*! @name Frame modification */ + //@{ + void translate(Vec &t); + void translate(const Vec &t); + // Some compilers complain about "overloading cannot distinguish from previous + // declaration" Simply comment out the following method and its associated + // implementation + void translate(qreal x, qreal y, qreal z); + void translate(qreal &x, qreal &y, qreal &z); + + void rotate(Quaternion &q); + void rotate(const Quaternion &q); + // Some compilers complain about "overloading cannot distinguish from previous + // declaration" Simply comment out the following method and its associated + // implementation + void rotate(qreal q0, qreal q1, qreal q2, qreal q3); + void rotate(qreal &q0, qreal &q1, qreal &q2, qreal &q3); + + void rotateAroundPoint(Quaternion &rotation, const Vec &point); + void rotateAroundPoint(const Quaternion &rotation, const Vec &point); + + void alignWithFrame(const Frame *const frame, bool move = false, + qreal threshold = 0.0); + void projectOnLine(const Vec &origin, const Vec &direction); + //@} + + /*! @name Coordinate system transformation of 3D coordinates */ + //@{ + Vec coordinatesOf(const Vec &src) const; + Vec inverseCoordinatesOf(const Vec &src) const; + Vec localCoordinatesOf(const Vec &src) const; + Vec localInverseCoordinatesOf(const Vec &src) const; + Vec coordinatesOfIn(const Vec &src, const Frame *const in) const; + Vec coordinatesOfFrom(const Vec &src, const Frame *const from) const; + + void getCoordinatesOf(const qreal src[3], qreal res[3]) const; + void getInverseCoordinatesOf(const qreal src[3], qreal res[3]) const; + void getLocalCoordinatesOf(const qreal src[3], qreal res[3]) const; + void getLocalInverseCoordinatesOf(const qreal src[3], qreal res[3]) const; + void getCoordinatesOfIn(const qreal src[3], qreal res[3], + const Frame *const in) const; + void getCoordinatesOfFrom(const qreal src[3], qreal res[3], + const Frame *const from) const; + //@} + + /*! @name Coordinate system transformation of vectors */ + // A frame is as a new coordinate system, defined with respect to a reference + // frame (the world coordinate system by default, see the "Composition of + // frame" section). + + // The transformOf() (resp. inverseTransformOf()) functions transform a 3D + // vector from (resp. to) the world coordinates system. This section defines + // the 3D vector transformation functions. See the Coordinate system + // transformation of 3D points above for the transformation of 3D points. The + // difference between the two sets of functions is simple: for vectors, only + // the rotational part of the transformations is taken into account, while + // translation is also considered for 3D points. + + // The length of the resulting transformed vector is identical to the one of + // the source vector for all the described functions. + + // When local is prepended to the names of the functions, the functions simply + // transform from (and to) the reference frame. + + // When In (resp. From) is appended to the names, the functions transform from + // (resp. To) the frame that is given as an argument. The frame does not need + // to be in the same branch or the hierarchical tree, and can be \c NULL (the + // world coordinates system). + + // Combining any of these functions with its inverse (in any order) leads to + // the identity. + //@{ + Vec transformOf(const Vec &src) const; + Vec inverseTransformOf(const Vec &src) const; + Vec localTransformOf(const Vec &src) const; + Vec localInverseTransformOf(const Vec &src) const; + Vec transformOfIn(const Vec &src, const Frame *const in) const; + Vec transformOfFrom(const Vec &src, const Frame *const from) const; + + void getTransformOf(const qreal src[3], qreal res[3]) const; + void getInverseTransformOf(const qreal src[3], qreal res[3]) const; + void getLocalTransformOf(const qreal src[3], qreal res[3]) const; + void getLocalInverseTransformOf(const qreal src[3], qreal res[3]) const; + void getTransformOfIn(const qreal src[3], qreal res[3], + const Frame *const in) const; + void getTransformOfFrom(const qreal src[3], qreal res[3], + const Frame *const from) const; + //@} + + /*! @name Constraint on the displacement */ + //@{ + /*! Returns the current constraint applied to the Frame. + + A \c NULL value (default) means that no Constraint is used to filter Frame + translation and rotation. See the Constraint class documentation for details. + + You may have to use a \c dynamic_cast to convert the result to a Constraint + derived class. */ + Constraint *constraint() const { return constraint_; } + /*! Sets the constraint() attached to the Frame. + + A \c NULL value means no constraint. The previous constraint() should be + deleted by the calling method if needed. */ + void setConstraint(Constraint *const constraint) { constraint_ = constraint; } + //@} + + /*! @name Associated matrices */ + //@{ +public: + const GLdouble *matrix() const; + void getMatrix(GLdouble m[4][4]) const; + void getMatrix(GLdouble m[16]) const; + + const GLdouble *worldMatrix() const; + void getWorldMatrix(GLdouble m[4][4]) const; + void getWorldMatrix(GLdouble m[16]) const; + + void setFromMatrix(const GLdouble m[4][4]); + void setFromMatrix(const GLdouble m[16]); + //@} + + /*! @name Inversion of the transformation */ + //@{ + Frame inverse() const; + /*! Returns the inverse() of the Frame world transformation. + + The orientation() of the new Frame is the Quaternion::inverse() of the + original orientation. Its position() is the negated and inverse rotated image + of the original position. + + The result Frame has a \c NULL referenceFrame() and a \c NULL constraint(). + + Use inverse() for a local (i.e. with respect to referenceFrame()) + transformation inverse. */ + Frame worldInverse() const { + return Frame(-(orientation().inverseRotate(position())), + orientation().inverse()); + } + //@} + + /*! @name XML representation */ + //@{ +public: + virtual QDomElement domElement(const QString &name, + QDomDocument &document) const; +public Q_SLOTS: + virtual void initFromDOMElement(const QDomElement &element); + //@} + +private: + // P o s i t i o n a n d o r i e n t a t i o n + Vec t_; + Quaternion q_; + + // C o n s t r a i n t s + Constraint *constraint_; + + // F r a m e c o m p o s i t i o n + const Frame *referenceFrame_; +}; + +}} // namespace CGAL::qglviewer + +#ifdef CGAL_HEADER_ONLY +//#include +#endif // CGAL_HEADER_ONLY + +#endif // QGLVIEWER_FRAME_H diff --git a/GraphicsView/include/CGAL/Qt/frame_impl.h b/GraphicsView/include/CGAL/Qt/frame_impl.h new file mode 100644 index 00000000000..acacb62c9b4 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/frame_impl.h @@ -0,0 +1,1186 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 + +#ifdef CGAL_HEADER_ONLY +#define CGAL_INLINE_FUNCTION inline + +#include + +#else +#define CGAL_INLINE_FUNCTION +#endif + +#include +#include +#include +#include + +namespace CGAL{ +namespace qglviewer{ + + +/*! Creates a default Frame. + + Its position() is (0,0,0) and it has an identity orientation() Quaternion. The + referenceFrame() and the constraint() are \c NULL. */ +CGAL_INLINE_FUNCTION +Frame::Frame() : constraint_(NULL), referenceFrame_(NULL) {} + +/*! Creates a Frame with a position() and an orientation(). + + See the Vec and Quaternion documentations for convenient constructors and + methods. + + The Frame is defined in the world coordinate system (its referenceFrame() is \c + NULL). It has a \c NULL associated constraint(). */ +CGAL_INLINE_FUNCTION +Frame::Frame(const Vec &position, const Quaternion &orientation) + : t_(position), q_(orientation), constraint_(NULL), referenceFrame_(NULL) {} + +/*! Equal operator. + + The referenceFrame() and constraint() pointers are copied. + + \attention Signal and slot connections are not copied. */ +CGAL_INLINE_FUNCTION +Frame &Frame::operator=(const Frame &frame) { + // Automatic compiler generated version would not emit the modified() signals + // as is done in setTranslationAndRotation. + setTranslationAndRotation(frame.translation(), frame.rotation()); + setConstraint(frame.constraint()); + setReferenceFrame(frame.referenceFrame()); + return *this; +} + +/*! Copy constructor. + + The translation() and rotation() as well as constraint() and referenceFrame() + pointers are copied. */ +CGAL_INLINE_FUNCTION +Frame::Frame(const Frame &frame) : QObject() { (*this) = frame; } + +/////////////////////////////// MATRICES ////////////////////////////////////// + +/*! Returns the 4x4 OpenGL transformation matrix represented by the Frame. + + This method should be used in conjunction with \c glMultMatrixd() to modify + the OpenGL modelview matrix from a Frame hierarchy. With this Frame hierarchy: + \code + Frame* body = new Frame(); + Frame* leftArm = new Frame(); + Frame* rightArm = new Frame(); + leftArm->setReferenceFrame(body); + rightArm->setReferenceFrame(body); + \endcode + + The associated OpenGL drawing code should look like: + \code + void Viewer::draw() + { + glPushMatrix(); + glMultMatrixd(body->matrix()); + drawBody(); + + glPushMatrix(); + glMultMatrixd(leftArm->matrix()); + drawArm(); + glPopMatrix(); + + glPushMatrix(); + glMultMatrixd(rightArm->matrix()); + drawArm(); + glPopMatrix(); + + glPopMatrix(); + } + \endcode + Note the use of nested \c glPushMatrix() and \c glPopMatrix() blocks to + represent the frame hierarchy: \c leftArm and \c rightArm are both correctly + drawn with respect to the \c body coordinate system. + + This matrix only represents the local Frame transformation (i.e. with respect + to the referenceFrame()). Use worldMatrix() to get the full Frame + transformation matrix (i.e. from the world to the Frame coordinate system). + These two match when the referenceFrame() is \c NULL. + + The result is only valid until the next call to matrix(), getMatrix(), + worldMatrix() or getWorldMatrix(). Use it immediately (as above) or use + getMatrix() instead. + + \attention The OpenGL format of the result is the transpose of the actual + mathematical European representation (translation is on the last \e line + instead of the last \e column). + + \note The scaling factor of the 4x4 matrix is 1.0. */ +CGAL_INLINE_FUNCTION +const GLdouble *Frame::matrix() const { + static GLdouble m[4][4]; + getMatrix(m); + return (const GLdouble *)(m); +} + +/*! \c GLdouble[4][4] version of matrix(). See also getWorldMatrix() and + * matrix(). */ +CGAL_INLINE_FUNCTION +void Frame::getMatrix(GLdouble m[4][4]) const { + q_.getMatrix(m); + + m[3][0] = t_[0]; + m[3][1] = t_[1]; + m[3][2] = t_[2]; +} + +/*! \c GLdouble[16] version of matrix(). See also getWorldMatrix() and matrix(). + */ +CGAL_INLINE_FUNCTION +void Frame::getMatrix(GLdouble m[16]) const { + q_.getMatrix(m); + + m[12] = t_[0]; + m[13] = t_[1]; + m[14] = t_[2]; +} + +/*! Returns a Frame representing the inverse of the Frame space transformation. + + The rotation() of the new Frame is the Quaternion::inverse() of the original + rotation. Its translation() is the negated inverse rotated image of the + original translation. + + If a Frame is considered as a space rigid transformation (translation and + rotation), the inverse() Frame performs the inverse transformation. + + Only the local Frame transformation (i.e. defined with respect to the + referenceFrame()) is inverted. Use worldInverse() for a global inverse. + + The resulting Frame has the same referenceFrame() as the Frame and a \c NULL + constraint(). + + \note The scaling factor of the 4x4 matrix is 1.0. */ +CGAL_INLINE_FUNCTION +Frame Frame::inverse() const { + Frame fr(-(q_.inverseRotate(t_)), q_.inverse()); + fr.setReferenceFrame(referenceFrame()); + return fr; +} + +/*! Returns the 4x4 OpenGL transformation matrix represented by the Frame. + + This method should be used in conjunction with \c glMultMatrixd() to modify + the OpenGL modelview matrix from a Frame: + \code + // The modelview here corresponds to the world coordinate system. + Frame fr(pos, Quaternion(from, to)); + glPushMatrix(); + glMultMatrixd(fr.worldMatrix()); + // draw object in the fr coordinate system. + glPopMatrix(); + \endcode + + This matrix represents the global Frame transformation: the entire + referenceFrame() hierarchy is taken into account to define the Frame + transformation from the world coordinate system. Use matrix() to get the local + Frame transformation matrix (i.e. defined with respect to the + referenceFrame()). These two match when the referenceFrame() is \c NULL. + + The OpenGL format of the result is the transpose of the actual mathematical + European representation (translation is on the last \e line instead of the + last \e column). + + \attention The result is only valid until the next call to matrix(), + getMatrix(), worldMatrix() or getWorldMatrix(). Use it immediately (as above) + or use getWorldMatrix() instead. + + \note The scaling factor of the 4x4 matrix is 1.0. */ +CGAL_INLINE_FUNCTION +const GLdouble *Frame::worldMatrix() const { + // This test is done for efficiency reasons (creates lots of temp objects + // otherwise). + if (referenceFrame()) { + static Frame fr; + fr.setTranslation(position()); + fr.setRotation(orientation()); + return fr.matrix(); + } else + return matrix(); +} + +/*! qreal[4][4] parameter version of worldMatrix(). See also getMatrix() and + * matrix(). */ +CGAL_INLINE_FUNCTION +void Frame::getWorldMatrix(GLdouble m[4][4]) const { + const GLdouble *mat = worldMatrix(); + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 4; ++j) + m[i][j] = mat[i * 4 + j]; +} + +/*! qreal[16] parameter version of worldMatrix(). See also getMatrix() and + * matrix(). */ +CGAL_INLINE_FUNCTION +void Frame::getWorldMatrix(GLdouble m[16]) const { + const GLdouble *mat = worldMatrix(); + for (int i = 0; i < 16; ++i) + m[i] = mat[i]; +} + +/*! This is an overloaded method provided for convenience. Same as + * setFromMatrix(). */ +CGAL_INLINE_FUNCTION +void Frame::setFromMatrix(const GLdouble m[4][4]) { + if (fabs(m[3][3]) < 1E-8) { + qWarning("Frame::setFromMatrix: Null homogeneous coefficient"); + return; + } + + qreal rot[3][3]; + for (int i = 0; i < 3; ++i) { + t_[i] = m[3][i] / m[3][3]; + for (int j = 0; j < 3; ++j) + // Beware of the transposition (OpenGL to European math) + rot[i][j] = m[j][i] / m[3][3]; + } + q_.setFromRotationMatrix(rot); + Q_EMIT modified(); +} + +/*! Sets the Frame from an OpenGL matrix representation (rotation in the upper + left 3x3 matrix and translation on the last line). + + Hence, if a code fragment looks like: + \code + GLdouble m[16]={...}; + glMultMatrixd(m); + \endcode + It is equivalent to write: + \code + Frame fr; + fr.setFromMatrix(m); + glMultMatrixd(fr.matrix()); + \endcode + + Using this conversion, you can benefit from the powerful Frame transformation + methods to translate points and vectors to and from the Frame coordinate system + to any other Frame coordinate system (including the world coordinate system). + See coordinatesOf() and transformOf(). + + Emits the modified() signal. See also matrix(), getMatrix() and + Quaternion::setFromRotationMatrix(). + + \attention A Frame does not contain a scale factor. The possible scaling in \p + m will not be converted into the Frame by this method. */ +CGAL_INLINE_FUNCTION +void Frame::setFromMatrix(const GLdouble m[16]) { + GLdouble mat[4][4]; + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 4; ++j) + mat[i][j] = m[i * 4 + j]; + setFromMatrix(mat); +} + +//////////////////// SET AND GET LOCAL TRANSLATION AND ROTATION +////////////////////////////////// + +/*! Same as setTranslation(), but with \p qreal parameters. */ +CGAL_INLINE_FUNCTION +void Frame::setTranslation(qreal x, qreal y, qreal z) { + setTranslation(Vec(x, y, z)); +} + +/*! Fill \c x, \c y and \c z with the translation() of the Frame. */ +CGAL_INLINE_FUNCTION +void Frame::getTranslation(qreal &x, qreal &y, qreal &z) const { + const Vec t = translation(); + x = t[0]; + y = t[1]; + z = t[2]; +} + +/*! Same as setRotation() but with \c qreal Quaternion parameters. */ +CGAL_INLINE_FUNCTION +void Frame::setRotation(qreal q0, qreal q1, qreal q2, qreal q3) { + setRotation(Quaternion(q0, q1, q2, q3)); +} + +/*! The \p q are set to the rotation() of the Frame. + +See Quaternion::Quaternion(qreal, qreal, qreal, qreal) for details on \c q. */ +CGAL_INLINE_FUNCTION +void Frame::getRotation(qreal &q0, qreal &q1, qreal &q2, qreal &q3) const { + const Quaternion q = rotation(); + q0 = q[0]; + q1 = q[1]; + q2 = q[2]; + q3 = q[3]; +} + +//////////////////////////////////////////////////////////////////////////////// + +/*! Translates the Frame of \p t (defined in the Frame coordinate system). + + The translation actually applied to the Frame may differ from \p t since it + can be filtered by the constraint(). Use translate(Vec&) or + setTranslationWithConstraint() to retrieve the filtered translation value. Use + setTranslation() to directly translate the Frame without taking the + constraint() into account. + + See also rotate(const Quaternion&). Emits the modified() signal. */ +CGAL_INLINE_FUNCTION +void Frame::translate(const Vec &t) { + Vec tbis = t; + translate(tbis); +} + +/*! Same as translate(const Vec&) but \p t may be modified to satisfy the + translation constraint(). Its new value corresponds to the translation that + has actually been applied to the Frame. */ +CGAL_INLINE_FUNCTION +void Frame::translate(Vec &t) { + if (constraint()) + constraint()->constrainTranslation(t, this); + t_ += t; + Q_EMIT modified(); +} + +/*! Same as translate(const Vec&) but with \c qreal parameters. */ +CGAL_INLINE_FUNCTION +void Frame::translate(qreal x, qreal y, qreal z) { + Vec t(x, y, z); + translate(t); +} + +/*! Same as translate(Vec&) but with \c qreal parameters. */ +CGAL_INLINE_FUNCTION +void Frame::translate(qreal &x, qreal &y, qreal &z) { + Vec t(x, y, z); + translate(t); + x = t[0]; + y = t[1]; + z = t[2]; +} + +/*! Rotates the Frame by \p q (defined in the Frame coordinate system): R = R*q. + + The rotation actually applied to the Frame may differ from \p q since it can + be filtered by the constraint(). Use rotate(Quaternion&) or + setRotationWithConstraint() to retrieve the filtered rotation value. Use + setRotation() to directly rotate the Frame without taking the constraint() + into account. + + See also translate(const Vec&). Emits the modified() signal. */ +CGAL_INLINE_FUNCTION +void Frame::rotate(const Quaternion &q) { + Quaternion qbis = q; + rotate(qbis); +} + +/*! Same as rotate(const Quaternion&) but \p q may be modified to satisfy the + rotation constraint(). Its new value corresponds to the rotation that has + actually been applied to the Frame. */ +CGAL_INLINE_FUNCTION +void Frame::rotate(Quaternion &q) { + if (constraint()) + constraint()->constrainRotation(q, this); + q_ *= q; + q_.normalize(); // Prevents numerical drift + Q_EMIT modified(); +} + +/*! Same as rotate(Quaternion&) but with \c qreal Quaternion parameters. */ +CGAL_INLINE_FUNCTION +void Frame::rotate(qreal &q0, qreal &q1, qreal &q2, qreal &q3) { + Quaternion q(q0, q1, q2, q3); + rotate(q); + q0 = q[0]; + q1 = q[1]; + q2 = q[2]; + q3 = q[3]; +} + +/*! Same as rotate(const Quaternion&) but with \c qreal Quaternion parameters. + */ +CGAL_INLINE_FUNCTION +void Frame::rotate(qreal q0, qreal q1, qreal q2, qreal q3) { + Quaternion q(q0, q1, q2, q3); + rotate(q); +} + +/*! Makes the Frame rotate() by \p rotation around \p point. + + \p point is defined in the world coordinate system, while the \p rotation axis + is defined in the Frame coordinate system. + + If the Frame has a constraint(), \p rotation is first constrained using + Constraint::constrainRotation(). The translation which results from the + filtered rotation around \p point is then computed and filtered using + Constraint::constrainTranslation(). The new \p rotation value corresponds to + the rotation that has actually been applied to the Frame. + + Emits the modified() signal. */ +CGAL_INLINE_FUNCTION +void Frame::rotateAroundPoint(Quaternion &rotation, const Vec &point) { + if (constraint()) + constraint()->constrainRotation(rotation, this); + q_ *= rotation; + q_.normalize(); // Prevents numerical drift + Vec trans = point + + Quaternion(inverseTransformOf(rotation.axis()), rotation.angle()) + .rotate(position() - point) - + t_; + if (constraint()) + constraint()->constrainTranslation(trans, this); + t_ += trans; + Q_EMIT modified(); +} + +/*! Same as rotateAroundPoint(), but with a \c const \p rotation Quaternion. + Note that the actual rotation may differ since it can be filtered by the + constraint(). */ +CGAL_INLINE_FUNCTION +void Frame::rotateAroundPoint(const Quaternion &rotation, const Vec &point) { + Quaternion rot = rotation; + rotateAroundPoint(rot, point); +} + +//////////////////// SET AND GET WORLD POSITION AND ORIENTATION +////////////////////////////////// + +/*! Sets the position() of the Frame, defined in the world coordinate system. +Emits the modified() signal. + +Use setTranslation() to define the \e local frame translation (with respect to +the referenceFrame()). The potential constraint() of the Frame is not taken into +account, use setPositionWithConstraint() instead. */ +CGAL_INLINE_FUNCTION +void Frame::setPosition(const Vec &position) { + if (referenceFrame()) + setTranslation(referenceFrame()->coordinatesOf(position)); + else + setTranslation(position); +} + +/*! Same as setPosition(), but with \c qreal parameters. */ +CGAL_INLINE_FUNCTION +void Frame::setPosition(qreal x, qreal y, qreal z) { + setPosition(Vec(x, y, z)); +} + +/*! Same as successive calls to setPosition() and then setOrientation(). + +Only one modified() signal is emitted, which is convenient if this signal is +connected to a CGAL::QGLViewer::update() slot. See also setTranslationAndRotation() +and setPositionAndOrientationWithConstraint(). */ +CGAL_INLINE_FUNCTION +void Frame::setPositionAndOrientation(const Vec &position, + const Quaternion &orientation) { + if (referenceFrame()) { + t_ = referenceFrame()->coordinatesOf(position); + q_ = referenceFrame()->orientation().inverse() * orientation; + } else { + t_ = position; + q_ = orientation; + } + Q_EMIT modified(); +} + +/*! Same as successive calls to setTranslation() and then setRotation(). + +Only one modified() signal is emitted, which is convenient if this signal is +connected to a CGAL::QGLViewer::update() slot. See also setPositionAndOrientation() +and setTranslationAndRotationWithConstraint(). */ +CGAL_INLINE_FUNCTION +void Frame::setTranslationAndRotation(const Vec &translation, + const Quaternion &rotation) { + t_ = translation; + q_ = rotation; + Q_EMIT modified(); +} + +/*! \p x, \p y and \p z are set to the position() of the Frame. */ +CGAL_INLINE_FUNCTION +void Frame::getPosition(qreal &x, qreal &y, qreal &z) const { + Vec p = position(); + x = p.x; + y = p.y; + z = p.z; +} + +/*! Sets the orientation() of the Frame, defined in the world coordinate system. +Emits the modified() signal. + +Use setRotation() to define the \e local frame rotation (with respect to the +referenceFrame()). The potential constraint() of the Frame is not taken into +account, use setOrientationWithConstraint() instead. */ +CGAL_INLINE_FUNCTION +void Frame::setOrientation(const Quaternion &orientation) { + if (referenceFrame()) + setRotation(referenceFrame()->orientation().inverse() * orientation); + else + setRotation(orientation); +} + +/*! Same as setOrientation(), but with \c qreal parameters. */ +CGAL_INLINE_FUNCTION +void Frame::setOrientation(qreal q0, qreal q1, qreal q2, qreal q3) { + setOrientation(Quaternion(q0, q1, q2, q3)); +} + +/*! Get the current orientation of the frame (same as orientation()). + Parameters are the orientation Quaternion values. + See also setOrientation(). */ + +/*! The \p q are set to the orientation() of the Frame. + +See Quaternion::Quaternion(qreal, qreal, qreal, qreal) for details on \c q. */ +CGAL_INLINE_FUNCTION +void Frame::getOrientation(qreal &q0, qreal &q1, qreal &q2, qreal &q3) const { + Quaternion o = orientation(); + q0 = o[0]; + q1 = o[1]; + q2 = o[2]; + q3 = o[3]; +} + +/*! Returns the position of the Frame, defined in the world coordinate system. + See also orientation(), setPosition() and translation(). */ +CGAL_INLINE_FUNCTION +Vec Frame::position() const { + if (referenceFrame_) + return inverseCoordinatesOf(Vec(0.0, 0.0, 0.0)); + else + return t_; +} + +/*! Returns the orientation of the Frame, defined in the world coordinate + system. See also position(), setOrientation() and rotation(). */ +CGAL_INLINE_FUNCTION +Quaternion Frame::orientation() const { + Quaternion res = rotation(); + const Frame *fr = referenceFrame(); + while (fr != NULL) { + res = fr->rotation() * res; + fr = fr->referenceFrame(); + } + return res; +} + +////////////////////// C o n s t r a i n t V e r s i o n s +///////////////////////////// + +/*! Same as setTranslation(), but \p translation is modified so that the + potential constraint() of the Frame is satisfied. + + Emits the modified() signal. See also setRotationWithConstraint() and + setPositionWithConstraint(). */ +CGAL_INLINE_FUNCTION +void Frame::setTranslationWithConstraint(Vec &translation) { + Vec deltaT = translation - this->translation(); + if (constraint()) + constraint()->constrainTranslation(deltaT, this); + + setTranslation(this->translation() + deltaT); + translation = this->translation(); +} + +/*! Same as setRotation(), but \p rotation is modified so that the potential + constraint() of the Frame is satisfied. + + Emits the modified() signal. See also setTranslationWithConstraint() and + setOrientationWithConstraint(). */ +CGAL_INLINE_FUNCTION +void Frame::setRotationWithConstraint(Quaternion &rotation) { + Quaternion deltaQ = this->rotation().inverse() * rotation; + if (constraint()) + constraint()->constrainRotation(deltaQ, this); + + // Prevent numerical drift + deltaQ.normalize(); + + setRotation(this->rotation() * deltaQ); + q_.normalize(); + rotation = this->rotation(); +} + +/*! Same as setTranslationAndRotation(), but \p translation and \p orientation + are modified to satisfy the constraint(). Emits the modified() signal. */ +CGAL_INLINE_FUNCTION +void Frame::setTranslationAndRotationWithConstraint(Vec &translation, + Quaternion &rotation) { + Vec deltaT = translation - this->translation(); + Quaternion deltaQ = this->rotation().inverse() * rotation; + + if (constraint()) { + constraint()->constrainTranslation(deltaT, this); + constraint()->constrainRotation(deltaQ, this); + } + + // Prevent numerical drift + deltaQ.normalize(); + + t_ += deltaT; + q_ *= deltaQ; + q_.normalize(); + + translation = this->translation(); + rotation = this->rotation(); + + Q_EMIT modified(); +} + +/*! Same as setPosition(), but \p position is modified so that the potential + constraint() of the Frame is satisfied. See also + setOrientationWithConstraint() and setTranslationWithConstraint(). */ +CGAL_INLINE_FUNCTION +void Frame::setPositionWithConstraint(Vec &position) { + if (referenceFrame()) + position = referenceFrame()->coordinatesOf(position); + + setTranslationWithConstraint(position); +} + +/*! Same as setOrientation(), but \p orientation is modified so that the + potential constraint() of the Frame is satisfied. See also + setPositionWithConstraint() and setRotationWithConstraint(). */ +CGAL_INLINE_FUNCTION +void Frame::setOrientationWithConstraint(Quaternion &orientation) { + if (referenceFrame()) + orientation = referenceFrame()->orientation().inverse() * orientation; + + setRotationWithConstraint(orientation); +} + +/*! Same as setPositionAndOrientation() but \p position and \p orientation are +modified to satisfy the constraint. Emits the modified() signal. */ +CGAL_INLINE_FUNCTION +void Frame::setPositionAndOrientationWithConstraint(Vec &position, + Quaternion &orientation) { + if (referenceFrame()) { + position = referenceFrame()->coordinatesOf(position); + orientation = referenceFrame()->orientation().inverse() * orientation; + } + setTranslationAndRotationWithConstraint(position, orientation); +} + +///////////////////////////// REFERENCE FRAMES +////////////////////////////////////////// + +/*! Sets the referenceFrame() of the Frame. + +The Frame translation() and rotation() are then defined in the referenceFrame() +coordinate system. Use position() and orientation() to express these in the +world coordinate system. + +Emits the modified() signal if \p refFrame differs from the current +referenceFrame(). + +Using this method, you can create a hierarchy of Frames. This hierarchy needs to +be a tree, which root is the world coordinate system (i.e. a \c NULL +referenceFrame()). A warning is printed and no action is performed if setting \p +refFrame as the referenceFrame() would create a loop in the Frame hierarchy (see +settingAsReferenceFrameWillCreateALoop()). */ +CGAL_INLINE_FUNCTION +void Frame::setReferenceFrame(const Frame *const refFrame) { + if (settingAsReferenceFrameWillCreateALoop(refFrame)) + qWarning("Frame::setReferenceFrame would create a loop in Frame hierarchy"); + else { + bool identical = (referenceFrame_ == refFrame); + referenceFrame_ = refFrame; + if (!identical) + Q_EMIT modified(); + } +} + +/*! Returns \c true if setting \p frame as the Frame's referenceFrame() would + create a loop in the Frame hierarchy. */ +CGAL_INLINE_FUNCTION +bool Frame::settingAsReferenceFrameWillCreateALoop(const Frame *const frame) { + const Frame *f = frame; + while (f != NULL) { + if (f == this) + return true; + f = f->referenceFrame(); + } + return false; +} + +///////////////////////// FRAME TRANSFORMATIONS OF 3D POINTS +///////////////////////////////// + +/*! Returns the Frame coordinates of a point \p src defined in the world + coordinate system (converts from world to Frame). + + inverseCoordinatesOf() performs the inverse convertion. transformOf() converts + 3D vectors instead of 3D coordinates. + + See the frameTransform example + for an illustration. */ +CGAL_INLINE_FUNCTION +Vec Frame::coordinatesOf(const Vec &src) const { + if (referenceFrame()) + return localCoordinatesOf(referenceFrame()->coordinatesOf(src)); + else + return localCoordinatesOf(src); +} + +/*! Returns the world coordinates of the point whose position in the Frame + coordinate system is \p src (converts from Frame to world). + + coordinatesOf() performs the inverse convertion. Use inverseTransformOf() to + transform 3D vectors instead of 3D coordinates. */ +CGAL_INLINE_FUNCTION +Vec Frame::inverseCoordinatesOf(const Vec &src) const { + const Frame *fr = this; + Vec res = src; + while (fr != NULL) { + res = fr->localInverseCoordinatesOf(res); + fr = fr->referenceFrame(); + } + return res; +} + +/*! Returns the Frame coordinates of a point \p src defined in the + referenceFrame() coordinate system (converts from referenceFrame() to Frame). + + localInverseCoordinatesOf() performs the inverse convertion. See also + localTransformOf(). */ +CGAL_INLINE_FUNCTION +Vec Frame::localCoordinatesOf(const Vec &src) const { + return rotation().inverseRotate(src - translation()); +} + +/*! Returns the referenceFrame() coordinates of a point \p src defined in the + Frame coordinate system (converts from Frame to referenceFrame()). + + localCoordinatesOf() performs the inverse convertion. See also + localInverseTransformOf(). */ +CGAL_INLINE_FUNCTION +Vec Frame::localInverseCoordinatesOf(const Vec &src) const { + return rotation().rotate(src) + translation(); +} + +/*! Returns the Frame coordinates of the point whose position in the \p from + coordinate system is \p src (converts from \p from to Frame). + + coordinatesOfIn() performs the inverse transformation. */ +CGAL_INLINE_FUNCTION +Vec Frame::coordinatesOfFrom(const Vec &src, const Frame *const from) const { + if (this == from) + return src; + else if (referenceFrame()) + return localCoordinatesOf(referenceFrame()->coordinatesOfFrom(src, from)); + else + return localCoordinatesOf(from->inverseCoordinatesOf(src)); +} + +/*! Returns the \p in coordinates of the point whose position in the Frame + coordinate system is \p src (converts from Frame to \p in). + + coordinatesOfFrom() performs the inverse transformation. */ +CGAL_INLINE_FUNCTION +Vec Frame::coordinatesOfIn(const Vec &src, const Frame *const in) const { + const Frame *fr = this; + Vec res = src; + while ((fr != NULL) && (fr != in)) { + res = fr->localInverseCoordinatesOf(res); + fr = fr->referenceFrame(); + } + + if (fr != in) + // in was not found in the branch of this, res is now expressed in the world + // coordinate system. Simply convert to in coordinate system. + res = in->coordinatesOf(res); + + return res; +} + +////// qreal[3] versions + +/*! Same as coordinatesOf(), but with \c qreal parameters. */ +CGAL_INLINE_FUNCTION +void Frame::getCoordinatesOf(const qreal src[3], qreal res[3]) const { + const Vec r = coordinatesOf(Vec(src)); + for (int i = 0; i < 3; ++i) + res[i] = r[i]; +} + +/*! Same as inverseCoordinatesOf(), but with \c qreal parameters. */ +CGAL_INLINE_FUNCTION +void Frame::getInverseCoordinatesOf(const qreal src[3], qreal res[3]) const { + const Vec r = inverseCoordinatesOf(Vec(src)); + for (int i = 0; i < 3; ++i) + res[i] = r[i]; +} + +/*! Same as localCoordinatesOf(), but with \c qreal parameters. */ +CGAL_INLINE_FUNCTION +void Frame::getLocalCoordinatesOf(const qreal src[3], qreal res[3]) const { + const Vec r = localCoordinatesOf(Vec(src)); + for (int i = 0; i < 3; ++i) + res[i] = r[i]; +} + +/*! Same as localInverseCoordinatesOf(), but with \c qreal parameters. */ +CGAL_INLINE_FUNCTION +void Frame::getLocalInverseCoordinatesOf(const qreal src[3], + qreal res[3]) const { + const Vec r = localInverseCoordinatesOf(Vec(src)); + for (int i = 0; i < 3; ++i) + res[i] = r[i]; +} + +/*! Same as coordinatesOfIn(), but with \c qreal parameters. */ +CGAL_INLINE_FUNCTION +void Frame::getCoordinatesOfIn(const qreal src[3], qreal res[3], + const Frame *const in) const { + const Vec r = coordinatesOfIn(Vec(src), in); + for (int i = 0; i < 3; ++i) + res[i] = r[i]; +} + +/*! Same as coordinatesOfFrom(), but with \c qreal parameters. */ +CGAL_INLINE_FUNCTION +void Frame::getCoordinatesOfFrom(const qreal src[3], qreal res[3], + const Frame *const from) const { + const Vec r = coordinatesOfFrom(Vec(src), from); + for (int i = 0; i < 3; ++i) + res[i] = r[i]; +} + +///////////////////////// FRAME TRANSFORMATIONS OF VECTORS +///////////////////////////////// + +/*! Returns the Frame transform of a vector \p src defined in the world + coordinate system (converts vectors from world to Frame). + + inverseTransformOf() performs the inverse transformation. coordinatesOf() + converts 3D coordinates instead of 3D vectors (here only the rotational part of + the transformation is taken into account). + + See the frameTransform example + for an illustration. */ +CGAL_INLINE_FUNCTION +Vec Frame::transformOf(const Vec &src) const { + if (referenceFrame()) + return localTransformOf(referenceFrame()->transformOf(src)); + else + return localTransformOf(src); +} + +/*! Returns the world transform of the vector whose coordinates in the Frame + coordinate system is \p src (converts vectors from Frame to world). + + transformOf() performs the inverse transformation. Use inverseCoordinatesOf() + to transform 3D coordinates instead of 3D vectors. */ +CGAL_INLINE_FUNCTION +Vec Frame::inverseTransformOf(const Vec &src) const { + const Frame *fr = this; + Vec res = src; + while (fr != NULL) { + res = fr->localInverseTransformOf(res); + fr = fr->referenceFrame(); + } + return res; +} + +/*! Returns the Frame transform of a vector \p src defined in the + referenceFrame() coordinate system (converts vectors from referenceFrame() to + Frame). + + localInverseTransformOf() performs the inverse transformation. See also + localCoordinatesOf(). */ +CGAL_INLINE_FUNCTION +Vec Frame::localTransformOf(const Vec &src) const { + return rotation().inverseRotate(src); +} + +/*! Returns the referenceFrame() transform of a vector \p src defined in the + Frame coordinate system (converts vectors from Frame to referenceFrame()). + + localTransformOf() performs the inverse transformation. See also + localInverseCoordinatesOf(). */ +CGAL_INLINE_FUNCTION +Vec Frame::localInverseTransformOf(const Vec &src) const { + return rotation().rotate(src); +} + +/*! Returns the Frame transform of the vector whose coordinates in the \p from + coordinate system is \p src (converts vectors from \p from to Frame). + + transformOfIn() performs the inverse transformation. */ +CGAL_INLINE_FUNCTION +Vec Frame::transformOfFrom(const Vec &src, const Frame *const from) const { + if (this == from) + return src; + else if (referenceFrame()) + return localTransformOf(referenceFrame()->transformOfFrom(src, from)); + else + return localTransformOf(from->inverseTransformOf(src)); +} + +/*! Returns the \p in transform of the vector whose coordinates in the Frame + coordinate system is \p src (converts vectors from Frame to \p in). + + transformOfFrom() performs the inverse transformation. */ +CGAL_INLINE_FUNCTION +Vec Frame::transformOfIn(const Vec &src, const Frame *const in) const { + const Frame *fr = this; + Vec res = src; + while ((fr != NULL) && (fr != in)) { + res = fr->localInverseTransformOf(res); + fr = fr->referenceFrame(); + } + + if (fr != in) + // in was not found in the branch of this, res is now expressed in the world + // coordinate system. Simply convert to in coordinate system. + res = in->transformOf(res); + + return res; +} + +///////////////// qreal[3] versions ////////////////////// + +/*! Same as transformOf(), but with \c qreal parameters. */ +CGAL_INLINE_FUNCTION +void Frame::getTransformOf(const qreal src[3], qreal res[3]) const { + Vec r = transformOf(Vec(src)); + for (int i = 0; i < 3; ++i) + res[i] = r[i]; +} + +/*! Same as inverseTransformOf(), but with \c qreal parameters. */ +CGAL_INLINE_FUNCTION +void Frame::getInverseTransformOf(const qreal src[3], qreal res[3]) const { + Vec r = inverseTransformOf(Vec(src)); + for (int i = 0; i < 3; ++i) + res[i] = r[i]; +} + +/*! Same as localTransformOf(), but with \c qreal parameters. */ +CGAL_INLINE_FUNCTION +void Frame::getLocalTransformOf(const qreal src[3], qreal res[3]) const { + Vec r = localTransformOf(Vec(src)); + for (int i = 0; i < 3; ++i) + res[i] = r[i]; +} + +/*! Same as localInverseTransformOf(), but with \c qreal parameters. */ +CGAL_INLINE_FUNCTION +void Frame::getLocalInverseTransformOf(const qreal src[3], qreal res[3]) const { + Vec r = localInverseTransformOf(Vec(src)); + for (int i = 0; i < 3; ++i) + res[i] = r[i]; +} + +/*! Same as transformOfIn(), but with \c qreal parameters. */ +CGAL_INLINE_FUNCTION +void Frame::getTransformOfIn(const qreal src[3], qreal res[3], + const Frame *const in) const { + Vec r = transformOfIn(Vec(src), in); + for (int i = 0; i < 3; ++i) + res[i] = r[i]; +} + +/*! Same as transformOfFrom(), but with \c qreal parameters. */ +CGAL_INLINE_FUNCTION +void Frame::getTransformOfFrom(const qreal src[3], qreal res[3], + const Frame *const from) const { + Vec r = transformOfFrom(Vec(src), from); + for (int i = 0; i < 3; ++i) + res[i] = r[i]; +} + +//////////////////////////// STATE ////////////////////////////// + +/*! Returns an XML \c QDomElement that represents the Frame. + + \p name is the name of the QDomElement tag. \p doc is the \c QDomDocument + factory used to create QDomElement. + + The resulting QDomElement looks like: + \code + + + + + \endcode + + Use initFromDOMElement() to restore the Frame state from the resulting \c + QDomElement. + + + See Vec::domElement() for a complete example. See also + + Quaternion::domElement(), Camera::domElement()... + + \attention The constraint() and referenceFrame() are not saved in the + QDomElement. */ +CGAL_INLINE_FUNCTION +QDomElement Frame::domElement(const QString &name, + QDomDocument &document) const { + // TODO: use translation and rotation instead when referenceFrame is coded... + QDomElement e = document.createElement(name); + e.appendChild(position().domElement("position", document)); + e.appendChild(orientation().domElement("orientation", document)); + return e; +} + +/*! Restores the Frame state from a \c QDomElement created by domElement(). + + See domElement() for the \c QDomElement syntax. See the + Vec::initFromDOMElement() and Quaternion::initFromDOMElement() documentations + for details on default values if an argument is missing. + + \attention The constraint() and referenceFrame() are not restored by this + method and are left unchanged. */ +CGAL_INLINE_FUNCTION +void Frame::initFromDOMElement(const QDomElement &element) { + // TODO: use translation and rotation instead when referenceFrame is coded... + + // Reset default values. Attention: destroys constraint. + // *this = Frame(); + // This instead ? Better : what is not set is not changed. + // setPositionAndOrientation(Vec(), Quaternion()); + + QDomElement child = element.firstChild().toElement(); + while (!child.isNull()) { + if (child.tagName() == "position") + setPosition(Vec(child)); + if (child.tagName() == "orientation") + setOrientation(Quaternion(child).normalized()); + + child = child.nextSibling().toElement(); + } +} + +///////////////////////////////// ALIGN ///////////////////////////////// + +/*! Aligns the Frame with \p frame, so that two of their axis are parallel. + +If one of the X, Y and Z axis of the Frame is almost parallel to any of the X, +Y, or Z axis of \p frame, the Frame is rotated so that these two axis actually +become parallel. + +If, after this first rotation, two other axis are also almost parallel, a second +alignment is performed. The two frames then have identical orientations, up to +90 degrees rotations. + +\p threshold measures how close two axis must be to be considered parallel. It +is compared with the absolute values of the dot product of the normalized axis. +As a result, useful range is sqrt(2)/2 (systematic alignment) to 1 (no +alignment). + +When \p move is set to \c true, the Frame position() is also affected by the +alignment. The new Frame's position() is such that the \p frame position +(computed with coordinatesOf(), in the Frame coordinates system) does not +change. + +\p frame may be \c NULL and then represents the world coordinate system (same +convention than for the referenceFrame()). + +The rotation (and translation when \p move is \c true) applied to the Frame are +filtered by the possible constraint(). */ +CGAL_INLINE_FUNCTION +void Frame::alignWithFrame(const Frame *const frame, bool move, + qreal threshold) { + Vec directions[2][3]; + for (unsigned short d = 0; d < 3; ++d) { + Vec dir((d == 0) ? 1.0 : 0.0, (d == 1) ? 1.0 : 0.0, (d == 2) ? 1.0 : 0.0); + if (frame) + directions[0][d] = frame->inverseTransformOf(dir); + else + directions[0][d] = dir; + directions[1][d] = inverseTransformOf(dir); + } + + qreal maxProj = 0.0; + qreal proj; + unsigned short index[2]; + index[0] = index[1] = 0; + for (unsigned short i = 0; i < 3; ++i) + for (unsigned short j = 0; j < 3; ++j) + if ((proj = fabs(directions[0][i] * directions[1][j])) >= maxProj) { + index[0] = i; + index[1] = j; + maxProj = proj; + } + + Frame old; + old = *this; + + qreal coef = directions[0][index[0]] * directions[1][index[1]]; + if (fabs(coef) >= threshold) { + const Vec axis = cross(directions[0][index[0]], directions[1][index[1]]); + qreal angle = asin(axis.norm()); + if (coef >= 0.0) + angle = -angle; + rotate(rotation().inverse() * Quaternion(axis, angle) * orientation()); + + // Try to align an other axis direction + unsigned short d = (unsigned short)((index[1] + 1) % 3); + Vec dir((d == 0) ? 1.0 : 0.0, (d == 1) ? 1.0 : 0.0, (d == 2) ? 1.0 : 0.0); + dir = inverseTransformOf(dir); + + qreal max = 0.0; + for (unsigned short i = 0; i < 3; ++i) { + qreal proj = fabs(directions[0][i] * dir); + if (proj > max) { + index[0] = i; + max = proj; + } + } + + if (max >= threshold) { + const Vec axis = cross(directions[0][index[0]], dir); + qreal angle = asin(axis.norm()); + if (directions[0][index[0]] * dir >= 0.0) + angle = -angle; + rotate(rotation().inverse() * Quaternion(axis, angle) * orientation()); + } + } + + if (move) { + Vec center; + if (frame) + center = frame->position(); + + translate(center - orientation().rotate(old.coordinatesOf(center)) - + translation()); + } +} + +/*! Translates the Frame so that its position() lies on the line defined by \p +origin and \p direction (defined in the world coordinate system). + +Simply uses an orthogonal projection. \p direction does not need to be +normalized. */ +CGAL_INLINE_FUNCTION +void Frame::projectOnLine(const Vec &origin, const Vec &direction) { + // If you are trying to find a bug here, because of memory problems, you waste + // your time. This is a bug in the gcc 3.3 compiler. Compile the library in + // debug mode and test. Uncommenting this line also seems to solve the + // problem. Horrible. cout << "position = " << position() << endl; If you + // found a problem or are using a different compiler, please let me know. + const Vec shift = origin - position(); + Vec proj = shift; + proj.projectOnAxis(direction); + translate(shift - proj); +} +}} diff --git a/GraphicsView/include/CGAL/Qt/image_interface.h b/GraphicsView/include/CGAL/Qt/image_interface.h new file mode 100644 index 00000000000..aa423eb5587 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/image_interface.h @@ -0,0 +1,70 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 + +#ifndef CGAL_IMAGE_INTERFACE_H +#define CGAL_IMAGE_INTERFACE_H +#include + +#include +#include +#include + +#include "ui_ImageInterface.h" +class ImageInterface: public QDialog, public Ui::ImageInterface +{ + Q_OBJECT + qreal ratio; + QWidget *currentlyFocused; +public: + ImageInterface(QWidget *parent, qreal ratio) + : QDialog(parent), ratio(ratio) + { + currentlyFocused = NULL; + setupUi(this); + connect(imgHeight, SIGNAL(valueChanged(int)), + this, SLOT(imgHeightValueChanged(int))); + + connect(imgWidth, SIGNAL(valueChanged(int)), + this, SLOT(imgWidthValueChanged(int))); + + connect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), + this, SLOT(onFocusChanged(QWidget*, QWidget*))); + } +private Q_SLOTS: + void imgHeightValueChanged(int i) + { + if(currentlyFocused == imgHeight + && ratioCheckBox->isChecked()) + {imgWidth->setValue(int(i*ratio));} + } + + void imgWidthValueChanged(int i) + { + if(currentlyFocused == imgWidth + && ratioCheckBox->isChecked()) + {imgHeight->setValue(int(i/ratio));} + } + + void onFocusChanged(QWidget*, QWidget* now) + { + currentlyFocused = now; + } +}; +#endif // CGAL_IMAGE_INTERFACE_H diff --git a/GraphicsView/include/CGAL/Qt/keyFrameInterpolator.h b/GraphicsView/include/CGAL/Qt/keyFrameInterpolator.h new file mode 100644 index 00000000000..2090b3f6de8 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/keyFrameInterpolator.h @@ -0,0 +1,372 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 +#ifndef QGLVIEWER_KEY_FRAME_INTERPOLATOR_H +#define QGLVIEWER_KEY_FRAME_INTERPOLATOR_H + +#include +#include +#include +#include +// Not actually needed, but some bad compilers (Microsoft VS6) complain. +//#include + +// If you compiler complains about incomplete type, uncomment the next line +// #include "frame.h" +// and comment "class Frame;" 3 lines below + +namespace CGAL{ +namespace qglviewer { +class Frame; +/*! \brief A keyFrame Catmull-Rom Frame interpolator. + \class KeyFrameInterpolator keyFrameInterpolator.h + CGAL::QGLViewer/keyFrameInterpolator.h + + A KeyFrameInterpolator holds keyFrames (that define a path) and a pointer to a + Frame of your application (which will be interpolated). When the user + startInterpolation(), the KeyFrameInterpolator regularly updates the frame() + position and orientation along the path. + + Here is a typical utilization example (see also the keyFrames example): \code + + + init() + { + // The KeyFrameInterpolator kfi is given the Frame that it will drive + over time. kfi = new KeyFrameInterpolator( new Frame() ); kfi->addKeyFrame( + Frame( Vec(1,0,0), Quaternion() ) ); kfi->addKeyFrame( new Frame( Vec(2,1,0), + Quaternion() ) ); + // ...and so on for all the keyFrames. + + // Ask for a display update after each update of the + KeyFrameInterpolator connect(kfi, SIGNAL(interpolated()), SLOT(update())); + + kfi->startInterpolation(); + } + + draw() + { + glPushMatrix(); + glMultMatrixd( kfi->frame()->matrix() ); + // Draw your object here. Its position and orientation are interpolated. + glPopMatrix(); + } + \endcode + + The keyFrames are defined by a Frame and a time, expressed in seconds. The + Frame can be provided as a const reference or as a pointer to a Frame (see the + addKeyFrame() methods). In the latter case, the path will automatically be + updated when the Frame is modified (using the Frame::modified() signal). + + The time has to be monotonously increasing over keyFrames. When + interpolationSpeed() equals 1.0 (default value), these times correspond to + actual user's seconds during interpolation (provided that your main loop is + fast enough). The interpolation is then real-time: the keyFrames will be + reached at their keyFrameTime(). + +

Interpolation details

+ + When the user startInterpolation(), a timer is started which will update the + frame()'s position and orientation every interpolationPeriod() milliseconds. + This update increases the interpolationTime() by interpolationPeriod() * + interpolationSpeed() milliseconds. + + Note that this mechanism ensures that the number of interpolation steps is + constant and equal to the total path duration() divided by the + interpolationPeriod() * interpolationSpeed(). This is especially useful for + benchmarking or movie creation (constant number of snapshots). + + During the interpolation, the KeyFrameInterpolator emits an interpolated() + signal, which will usually be connected to the CGAL::QGLViewer::update() slot. The + interpolation is stopped when interpolationTime() is greater than the + lastTime() (unless loopInterpolation() is \c true) and the endReached() signal + is then emitted. + + Note that a Camera has Camera::keyFrameInterpolator(), that can be used to + drive the Camera along a path, or to restore a saved position (a path made of + a single keyFrame). Press Alt+Fx to define a new keyFrame for path x. Pressing + Fx plays/pauses path interpolation. See CGAL::QGLViewer::pathKey() and the keyboard page for details. + + \attention If a Constraint is attached to the frame() (see + Frame::constraint()), it should be deactivated before + interpolationIsStarted(), otherwise the interpolated motion (computed as if + there was no constraint) will probably be erroneous. + +

Retrieving interpolated values

+ + This code defines a KeyFrameInterpolator, and displays the positions that will + be followed by the frame() along the path: \code KeyFrameInterpolator kfi( new + Frame() ); + // calls to kfi.addKeyFrame() to define the path. + + const qreal deltaTime = 0.04; // output a position every deltaTime seconds + for (qreal time=kfi.firstTime(); time<=kfi.lastTime(); time += deltaTime) + { + kfi.interpolateAtTime(time); + cout << "t=" << time << "\tpos=" << kfi.frame()->position() << endl; + } + \endcode + You may want to temporally disconnect the \c kfi interpolated() signal from + the CGAL::QGLViewer::update() slot before calling this code. \nosubgrouping */ +class CGAL_QT_EXPORT KeyFrameInterpolator : public QObject { + // todo closedPath, insertKeyFrames, deleteKeyFrame, replaceKeyFrame + Q_OBJECT + +public: + KeyFrameInterpolator(Frame *fr = NULL); + virtual ~KeyFrameInterpolator(); + +Q_SIGNALS: + /*! This signal is emitted whenever the frame() state is interpolated. + + The emission of this signal triggers the synchronous emission of the frame() + Frame::interpolated() signal, which may also be useful. + + This signal should especially be connected to your CGAL::QGLViewer::update() slot, + so that the display is updated after every update of the KeyFrameInterpolator + frame(): \code connect(myKeyFrameInterpolator, SIGNAL(interpolated()), + SLOT(update())); \endcode Use the CGAL::QGLViewer::QGLViewerPool() to connect the + signal to all the viewers. + + Note that the CGAL::QGLViewer::camera() Camera::keyFrameInterpolator() created using + CGAL::QGLViewer::pathKey() have their interpolated() signals automatically connected + to the CGAL::QGLViewer::update() slot. */ + void interpolated(); + + /*! This signal is emitted when the interpolation reaches the first (when + interpolationSpeed() is negative) or the last keyFrame. + + When loopInterpolation() is \c true, interpolationTime() is reset and the + interpolation continues. It otherwise stops. */ + void endReached(); + + /*! @name Path creation */ + //@{ +public Q_SLOTS: + void addKeyFrame(const Frame &frame); + void addKeyFrame(const Frame &frame, qreal time); + + void addKeyFrame(const Frame *const frame); + void addKeyFrame(const Frame *const frame, qreal time); + + void deletePath(); + //@} + + /*! @name Associated Frame */ + //@{ +public: + /*! Returns the associated Frame and that is interpolated by the + KeyFrameInterpolator. + + When interpolationIsStarted(), this Frame's position and orientation will + regularly be updated by a timer, so that they follow the KeyFrameInterpolator + path. + + Set using setFrame() or with the KeyFrameInterpolator constructor. */ + Frame *frame() const { return frame_; } + +public Q_SLOTS: + void setFrame(Frame *const frame); + //@} + + /*! @name Path parameters */ + //@{ +public: + Frame keyFrame(int index) const; + qreal keyFrameTime(int index) const; + /*! Returns the number of keyFrames used by the interpolation. Use + * addKeyFrame() to add new keyFrames. */ + int numberOfKeyFrames() const { return keyFrame_.count(); } + qreal duration() const; + qreal firstTime() const; + qreal lastTime() const; + //@} + + /*! @name Interpolation parameters */ + //@{ +public: + /*! Returns the current interpolation time (in seconds) along the + KeyFrameInterpolator path. + + This time is regularly updated when interpolationIsStarted(). Can be set + directly with setInterpolationTime() or interpolateAtTime(). */ + qreal interpolationTime() const { return interpolationTime_; } + /*! Returns the current interpolation speed. + + Default value is 1.0, which means keyFrameTime() will be matched during the + interpolation (provided that your main loop is fast enough). + + A negative value will result in a reverse interpolation of the keyFrames. See + also interpolationPeriod(). */ + qreal interpolationSpeed() const { return interpolationSpeed_; } + /*! Returns the current interpolation period, expressed in milliseconds. + + The update of the frame() state will be done by a timer at this period when + interpolationIsStarted(). + + This period (multiplied by interpolationSpeed()) is added to the + interpolationTime() at each update, and the frame() state is modified + accordingly (see interpolateAtTime()). Default value is 40 milliseconds. */ + int interpolationPeriod() const { return period_; } + /*! Returns \c true when the interpolation is played in an infinite loop. + + When \c false (default), the interpolation stops when interpolationTime() + reaches firstTime() (with negative interpolationSpeed()) or lastTime(). + + interpolationTime() is otherwise reset to firstTime() (+ interpolationTime() - + lastTime()) (and inversely for negative interpolationSpeed()) and + interpolation continues. + + In both cases, the endReached() signal is emitted. */ + bool loopInterpolation() const { return loopInterpolation_; } +#ifndef DOXYGEN + /*! Whether or not (default) the path defined by the keyFrames is a closed + loop. When \c true, the last and the first KeyFrame are linked by a new spline + segment. + + Use setLoopInterpolation() to create a continuous animation over the entire + path. \attention The closed path feature is not yet implemented. */ + bool closedPath() const { return closedPath_; } +#endif +public Q_SLOTS: + /*! Sets the interpolationTime(). + + \attention The frame() state is not affected by this method. Use this function + to define the starting time of a future interpolation (see + startInterpolation()). Use interpolateAtTime() to actually interpolate at a + given time. */ + void setInterpolationTime(qreal time) { interpolationTime_ = time; } + /*! Sets the interpolationSpeed(). Negative or null values are allowed. */ + void setInterpolationSpeed(qreal speed) { interpolationSpeed_ = speed; } + /*! Sets the interpolationPeriod(). */ + void setInterpolationPeriod(int period) { period_ = period; } + /*! Sets the loopInterpolation() value. */ + void setLoopInterpolation(bool loop = true) { loopInterpolation_ = loop; } +#ifndef DOXYGEN + /*! Sets the closedPath() value. \attention The closed path feature is not yet + * implemented. */ + void setClosedPath(bool closed = true) { closedPath_ = closed; } +#endif + //@} + + /*! @name Interpolation */ + //@{ +public: + /*! Returns \c true when the interpolation is being performed. Use + startInterpolation(), stopInterpolation() or toggleInterpolation() to modify + this state. */ + bool interpolationIsStarted() const { return interpolationStarted_; } +public Q_SLOTS: + void startInterpolation(int period = -1); + void stopInterpolation(); + void resetInterpolation(); + /*! Calls startInterpolation() or stopInterpolation(), depending on + * interpolationIsStarted(). */ + void toggleInterpolation() { + if (interpolationIsStarted()) + stopInterpolation(); + else + startInterpolation(); + } + virtual void interpolateAtTime(qreal time); + //@} + + /*! @name XML representation */ + //@{ +public: + virtual QDomElement domElement(const QString &name, + QDomDocument &document) const; + virtual void initFromDOMElement(const QDomElement &element); + //@} + +private Q_SLOTS: + virtual void update(); + virtual void invalidateValues() { + valuesAreValid_ = false; + pathIsValid_ = false; + splineCacheIsValid_ = false; + } + +private: + // Copy constructor and opertor= are declared private and undefined + // Prevents everyone from trying to use them + // KeyFrameInterpolator(const KeyFrameInterpolator& kfi); + // KeyFrameInterpolator& operator=(const KeyFrameInterpolator& kfi); + + void updateCurrentKeyFrameForTime(qreal time); + void updateModifiedFrameValues(); + void updateSplineCache(); + +#ifndef DOXYGEN + // Internal private KeyFrame representation + class KeyFrame { + public: + KeyFrame(const Frame &fr, qreal t); + KeyFrame(const Frame *fr, qreal t); + + Vec position() const { return p_; } + Quaternion orientation() const { return q_; } + Vec tgP() const { return tgP_; } + Quaternion tgQ() const { return tgQ_; } + qreal time() const { return time_; } + const Frame *frame() const { return frame_; } + void updateValuesFromPointer(); + void flipOrientationIfNeeded(const Quaternion &prev); + void computeTangent(const KeyFrame *const prev, const KeyFrame *const next); + + private: + Vec p_, tgP_; + Quaternion q_, tgQ_; + qreal time_; + const Frame *const frame_; + }; +#endif + + // K e y F r a m e s + mutable QList keyFrame_; + QMutableListIterator *currentFrame_[4]; + QList path_; + + // A s s o c i a t e d f r a m e + Frame *frame_; + + // R h y t h m + QTimer timer_; + int period_; + qreal interpolationTime_; + qreal interpolationSpeed_; + bool interpolationStarted_; + + // M i s c + bool closedPath_; + bool loopInterpolation_; + + // C a c h e d v a l u e s a n d f l a g s + bool pathIsValid_; + bool valuesAreValid_; + bool currentFrameValid_; + bool splineCacheIsValid_; + Vec v1, v2; +}; + +}} // namespace CGAL::qglviewer + +#endif // QGLVIEWER_KEY_FRAME_INTERPOLATOR_H diff --git a/GraphicsView/include/CGAL/Qt/keyFrameInterpolator_impl.h b/GraphicsView/include/CGAL/Qt/keyFrameInterpolator_impl.h new file mode 100644 index 00000000000..a591734c161 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/keyFrameInterpolator_impl.h @@ -0,0 +1,586 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 +#ifdef CGAL_HEADER_ONLY +#define CGAL_INLINE_FUNCTION inline + +#include + +#else +#define CGAL_INLINE_FUNCTION +#endif + +#include +#include + +namespace CGAL{ +namespace qglviewer{ + + +/*! Creates a KeyFrameInterpolator, with \p frame as associated frame(). + + The frame() can be set or changed using setFrame(). + + interpolationTime(), interpolationSpeed() and interpolationPeriod() are set to + their default values. */ +CGAL_INLINE_FUNCTION +KeyFrameInterpolator::KeyFrameInterpolator(Frame *frame) + : frame_(NULL), period_(40), interpolationTime_(0.0), + interpolationSpeed_(1.0), interpolationStarted_(false), + closedPath_(false), loopInterpolation_(false), pathIsValid_(false), + valuesAreValid_(true), currentFrameValid_(false) +// #CONNECTION# Values cut pasted initFromDOMElement() +{ + setFrame(frame); + for (int i = 0; i < 4; ++i) + currentFrame_[i] = new QMutableListIterator(keyFrame_); + connect(&timer_, SIGNAL(timeout()), SLOT(update())); +} + +/*! Virtual destructor. Clears the keyFrame path. */ +CGAL_INLINE_FUNCTION +KeyFrameInterpolator::~KeyFrameInterpolator() { + deletePath(); + for (int i = 0; i < 4; ++i) + delete currentFrame_[i]; +} + +/*! Sets the frame() associated to the KeyFrameInterpolator. */ +CGAL_INLINE_FUNCTION +void KeyFrameInterpolator::setFrame(Frame *const frame) { + if (this->frame()) + disconnect(this, SIGNAL(interpolated()), this->frame(), + SIGNAL(interpolated())); + + frame_ = frame; + + if (this->frame()) + connect(this, SIGNAL(interpolated()), this->frame(), + SIGNAL(interpolated())); +} + +/*! Updates frame() state according to current interpolationTime(). Then adds + interpolationPeriod()*interpolationSpeed() to interpolationTime(). + + This internal method is called by a timer when interpolationIsStarted(). It + can be used for debugging purpose. stopInterpolation() is called when + interpolationTime() reaches firstTime() or lastTime(), unless + loopInterpolation() is \c true. */ +CGAL_INLINE_FUNCTION +void KeyFrameInterpolator::update() { + interpolateAtTime(interpolationTime()); + + interpolationTime_ += interpolationSpeed() * interpolationPeriod() / 1000.0; + + if (interpolationTime() > keyFrame_.last()->time()) { + if (loopInterpolation()) + setInterpolationTime(keyFrame_.first()->time() + interpolationTime_ - + keyFrame_.last()->time()); + else { + // Make sure last KeyFrame is reached and displayed + interpolateAtTime(keyFrame_.last()->time()); + stopInterpolation(); + } + Q_EMIT endReached(); + } else if (interpolationTime() < keyFrame_.first()->time()) { + if (loopInterpolation()) + setInterpolationTime(keyFrame_.last()->time() - + keyFrame_.first()->time() + interpolationTime_); + else { + // Make sure first KeyFrame is reached and displayed + interpolateAtTime(keyFrame_.first()->time()); + stopInterpolation(); + } + Q_EMIT endReached(); + } +} + +/*! Starts the interpolation process. + + A timer is started with an interpolationPeriod() period that updates the + frame()'s position and orientation. interpolationIsStarted() will return \c + true until stopInterpolation() or toggleInterpolation() is called. + + If \p period is positive, it is set as the new interpolationPeriod(). The + previous interpolationPeriod() is used otherwise (default). + + If interpolationTime() is larger than lastTime(), interpolationTime() is reset + to firstTime() before interpolation starts (and inversely for negative + interpolationSpeed()). + + Use setInterpolationTime() before calling this method to change the starting + interpolationTime(). + + See the keyFrames example for an + illustration. + + You may also be interested in CGAL::QGLViewer::animate() and + CGAL::QGLViewer::startAnimation(). + + \attention The keyFrames must be defined (see addKeyFrame()) \e before you + startInterpolation(), or else the interpolation will naturally immediately + stop. */ +CGAL_INLINE_FUNCTION +void KeyFrameInterpolator::startInterpolation(int period) { + if (period >= 0) + setInterpolationPeriod(period); + + if (!keyFrame_.isEmpty()) { + if ((interpolationSpeed() > 0.0) && + (interpolationTime() >= keyFrame_.last()->time())) + setInterpolationTime(keyFrame_.first()->time()); + if ((interpolationSpeed() < 0.0) && + (interpolationTime() <= keyFrame_.first()->time())) + setInterpolationTime(keyFrame_.last()->time()); + timer_.start(interpolationPeriod()); + interpolationStarted_ = true; + update(); + } +} + +/*! Stops an interpolation started with startInterpolation(). See + * interpolationIsStarted() and toggleInterpolation(). */ +CGAL_INLINE_FUNCTION +void KeyFrameInterpolator::stopInterpolation() { + timer_.stop(); + interpolationStarted_ = false; +} + +/*! Stops the interpolation and resets interpolationTime() to the firstTime(). + +If desired, call interpolateAtTime() after this method to actually move the +frame() to firstTime(). */ +CGAL_INLINE_FUNCTION +void KeyFrameInterpolator::resetInterpolation() { + stopInterpolation(); + setInterpolationTime(firstTime()); +} + +/*! Appends a new keyFrame to the path, with its associated \p time (in + seconds). + + The keyFrame is given as a pointer to a Frame, which will be connected to the + KeyFrameInterpolator: when \p frame is modified, the KeyFrameInterpolator path + is updated accordingly. This allows for dynamic paths, where keyFrame can be + edited, even during the interpolation. See the keyFrames example for an illustration. + + \c NULL \p frame pointers are silently ignored. The keyFrameTime() has to be + monotonously increasing over keyFrames. + + Use addKeyFrame(const Frame&, qreal) to add keyFrame by values. */ +CGAL_INLINE_FUNCTION +void KeyFrameInterpolator::addKeyFrame(const Frame *const frame, qreal time) { + if (!frame) + return; + + if (keyFrame_.isEmpty()) + interpolationTime_ = time; + + if ((!keyFrame_.isEmpty()) && (keyFrame_.last()->time() > time)) + qWarning( + "Error in KeyFrameInterpolator::addKeyFrame: time is not monotone"); + else + keyFrame_.append(new KeyFrame(frame, time)); + connect(frame, SIGNAL(modified()), SLOT(invalidateValues())); + valuesAreValid_ = false; + pathIsValid_ = false; + currentFrameValid_ = false; + resetInterpolation(); +} + +/*! Appends a new keyFrame to the path, with its associated \p time (in + seconds). + + The path will use the current \p frame state. If you want the path to change + when \p frame is modified, you need to pass a \e pointer to the Frame instead + (see addKeyFrame(const Frame*, qreal)). + + The keyFrameTime() have to be monotonously increasing over keyFrames. */ +CGAL_INLINE_FUNCTION +void KeyFrameInterpolator::addKeyFrame(const Frame &frame, qreal time) { + if (keyFrame_.isEmpty()) + interpolationTime_ = time; + + if ((!keyFrame_.isEmpty()) && (keyFrame_.last()->time() > time)) + qWarning( + "Error in KeyFrameInterpolator::addKeyFrame: time is not monotone"); + else + keyFrame_.append(new KeyFrame(frame, time)); + + valuesAreValid_ = false; + pathIsValid_ = false; + currentFrameValid_ = false; + resetInterpolation(); +} + +/*! Appends a new keyFrame to the path. + + Same as addKeyFrame(const Frame* frame, qreal), except that the keyFrameTime() + is set to the previous keyFrameTime() plus one second (or 0.0 if there is no + previous keyFrame). */ +CGAL_INLINE_FUNCTION +void KeyFrameInterpolator::addKeyFrame(const Frame *const frame) { + qreal time; + if (keyFrame_.isEmpty()) + time = 0.0; + else + time = lastTime() + 1.0; + + addKeyFrame(frame, time); +} + +/*! Appends a new keyFrame to the path. + + Same as addKeyFrame(const Frame& frame, qreal), except that the keyFrameTime() + is automatically set to previous keyFrameTime() plus one second (or 0.0 if + there is no previous keyFrame). */ +CGAL_INLINE_FUNCTION +void KeyFrameInterpolator::addKeyFrame(const Frame &frame) { + qreal time; + if (keyFrame_.isEmpty()) + time = 0.0; + else + time = keyFrame_.last()->time() + 1.0; + + addKeyFrame(frame, time); +} + +/*! Removes all keyFrames from the path. The numberOfKeyFrames() is set to 0. */ +CGAL_INLINE_FUNCTION +void KeyFrameInterpolator::deletePath() { + stopInterpolation(); + qDeleteAll(keyFrame_); + keyFrame_.clear(); + pathIsValid_ = false; + valuesAreValid_ = false; + currentFrameValid_ = false; +} + + +CGAL_INLINE_FUNCTION +void KeyFrameInterpolator::updateModifiedFrameValues() { + Quaternion prevQ = keyFrame_.first()->orientation(); + KeyFrame *kf; + for (int i = 0; i < keyFrame_.size(); ++i) { + kf = keyFrame_.at(i); + if (kf->frame()) + kf->updateValuesFromPointer(); + kf->flipOrientationIfNeeded(prevQ); + prevQ = kf->orientation(); + } + + KeyFrame *prev = keyFrame_.first(); + kf = keyFrame_.first(); + int index = 1; + while (kf) { + KeyFrame *next = (index < keyFrame_.size()) ? keyFrame_.at(index) : NULL; + index++; + if (next) + kf->computeTangent(prev, next); + else + kf->computeTangent(prev, kf); + prev = kf; + kf = next; + } + valuesAreValid_ = true; +} + +/*! Returns the Frame associated with the keyFrame at index \p index. + + See also keyFrameTime(). \p index has to be in the range + 0..numberOfKeyFrames()-1. + + \note If this keyFrame was defined using a pointer to a Frame (see + addKeyFrame(const Frame* const)), the \e current pointed Frame state is + returned. */ +CGAL_INLINE_FUNCTION +Frame KeyFrameInterpolator::keyFrame(int index) const { + const KeyFrame *const kf = keyFrame_.at(index); + return Frame(kf->position(), kf->orientation()); +} + +/*! Returns the time corresponding to the \p index keyFrame. + + See also keyFrame(). \p index has to be in the range 0..numberOfKeyFrames()-1. + */ +CGAL_INLINE_FUNCTION +qreal KeyFrameInterpolator::keyFrameTime(int index) const { + return keyFrame_.at(index)->time(); +} + +/*! Returns the duration of the KeyFrameInterpolator path, expressed in seconds. + + Simply corresponds to lastTime() - firstTime(). Returns 0.0 if the path has + less than 2 keyFrames. See also keyFrameTime(). */ +CGAL_INLINE_FUNCTION +qreal KeyFrameInterpolator::duration() const { + return lastTime() - firstTime(); +} + +/*! Returns the time corresponding to the first keyFrame, expressed in seconds. + +Returns 0.0 if the path is empty. See also lastTime(), duration() and +keyFrameTime(). */ +CGAL_INLINE_FUNCTION +qreal KeyFrameInterpolator::firstTime() const { + if (keyFrame_.isEmpty()) + return 0.0; + else + return keyFrame_.first()->time(); +} + +/*! Returns the time corresponding to the last keyFrame, expressed in seconds. + +Returns 0.0 if the path is empty. See also firstTime(), duration() and +keyFrameTime(). */ +CGAL_INLINE_FUNCTION +qreal KeyFrameInterpolator::lastTime() const { + if (keyFrame_.isEmpty()) + return 0.0; + else + return keyFrame_.last()->time(); +} + +CGAL_INLINE_FUNCTION +void KeyFrameInterpolator::updateCurrentKeyFrameForTime(qreal time) { + // Assertion: times are sorted in monotone order. + // Assertion: keyFrame_ is not empty + + // TODO: Special case for loops when closed path is implemented !! + if (!currentFrameValid_) + // Recompute everything from scrach + currentFrame_[1]->toFront(); + + while (currentFrame_[1]->peekNext()->time() > time) { + currentFrameValid_ = false; + if (!currentFrame_[1]->hasPrevious()) + break; + currentFrame_[1]->previous(); + } + + if (!currentFrameValid_) + *currentFrame_[2] = *currentFrame_[1]; + + while (currentFrame_[2]->peekNext()->time() < time) { + currentFrameValid_ = false; + if (!currentFrame_[2]->hasNext()) + break; + currentFrame_[2]->next(); + } + + if (!currentFrameValid_) { + *currentFrame_[1] = *currentFrame_[2]; + if ((currentFrame_[1]->hasPrevious()) && + (time < currentFrame_[2]->peekNext()->time())) + currentFrame_[1]->previous(); + + *currentFrame_[0] = *currentFrame_[1]; + if (currentFrame_[0]->hasPrevious()) + currentFrame_[0]->previous(); + + *currentFrame_[3] = *currentFrame_[2]; + if (currentFrame_[3]->hasNext()) + currentFrame_[3]->next(); + + currentFrameValid_ = true; + splineCacheIsValid_ = false; + } + + // cout << "Time = " << time << " : " << currentFrame_[0]->peekNext()->time() + // << " , " << currentFrame_[1]->peekNext()->time() << " , " << + // currentFrame_[2]->peekNext()->time() << " , " << + // currentFrame_[3]->peekNext()->time() << endl; +} + +CGAL_INLINE_FUNCTION +void KeyFrameInterpolator::updateSplineCache() { + Vec delta = currentFrame_[2]->peekNext()->position() - + currentFrame_[1]->peekNext()->position(); + v1 = 3.0 * delta - 2.0 * currentFrame_[1]->peekNext()->tgP() - + currentFrame_[2]->peekNext()->tgP(); + v2 = -2.0 * delta + currentFrame_[1]->peekNext()->tgP() + + currentFrame_[2]->peekNext()->tgP(); + splineCacheIsValid_ = true; +} + +/*! Interpolate frame() at time \p time (expressed in seconds). + interpolationTime() is set to \p time and frame() is set accordingly. + + If you simply want to change interpolationTime() but not the frame() state, + use setInterpolationTime() instead. + + Emits the interpolated() signal and makes the frame() emit the + Frame::interpolated() signal. */ +CGAL_INLINE_FUNCTION +void KeyFrameInterpolator::interpolateAtTime(qreal time) { + setInterpolationTime(time); + + if ((keyFrame_.isEmpty()) || (!frame())) + return; + + if (!valuesAreValid_) + updateModifiedFrameValues(); + + updateCurrentKeyFrameForTime(time); + + if (!splineCacheIsValid_) + updateSplineCache(); + + qreal alpha; + qreal dt = currentFrame_[2]->peekNext()->time() - + currentFrame_[1]->peekNext()->time(); + if (dt == 0.0) + alpha = 0.0; + else + alpha = (time - currentFrame_[1]->peekNext()->time()) / dt; + + // Linear interpolation - debug + // Vec pos = alpha*(currentFrame_[2]->peekNext()->position()) + + // (1.0-alpha)*(currentFrame_[1]->peekNext()->position()); + Vec pos = + currentFrame_[1]->peekNext()->position() + + alpha * (currentFrame_[1]->peekNext()->tgP() + alpha * (v1 + alpha * v2)); + Quaternion q = Quaternion::squad( + currentFrame_[1]->peekNext()->orientation(), + currentFrame_[1]->peekNext()->tgQ(), currentFrame_[2]->peekNext()->tgQ(), + currentFrame_[2]->peekNext()->orientation(), alpha); + frame()->setPositionAndOrientationWithConstraint(pos, q); + + Q_EMIT interpolated(); +} + +/*! Returns an XML \c QDomElement that represents the KeyFrameInterpolator. + + The resulting QDomElement holds the KeyFrameInterpolator parameters as well as + the path keyFrames (if the keyFrame is defined by a pointer to a Frame, use its + current value). + + \p name is the name of the QDomElement tag. \p doc is the \c QDomDocument + factory used to create QDomElement. + + Use initFromDOMElement() to restore the ManipulatedFrame state from the + resulting QDomElement. + + + See Vec::domElement() for a complete example. See also + Quaternion::domElement(), Camera::domElement()... + + Note that the Camera::keyFrameInterpolator() are automatically saved by + CGAL::QGLViewer::saveStateToFile() when a CGAL::QGLViewer is closed. */ +CGAL_INLINE_FUNCTION +QDomElement KeyFrameInterpolator::domElement(const QString &name, + QDomDocument &document) const { + QDomElement de = document.createElement(name); + int count = 0; + Q_FOREACH (KeyFrame *kf, keyFrame_) { + Frame fr(kf->position(), kf->orientation()); + QDomElement kfNode = fr.domElement("KeyFrame", document); + kfNode.setAttribute("index", QString::number(count)); + kfNode.setAttribute("time", QString::number(kf->time())); + de.appendChild(kfNode); + ++count; + } + de.setAttribute("nbKF", QString::number(keyFrame_.count())); + de.setAttribute("time", QString::number(interpolationTime())); + de.setAttribute("speed", QString::number(interpolationSpeed())); + de.setAttribute("period", QString::number(interpolationPeriod())); + DomUtils::setBoolAttribute(de, "closedPath", closedPath()); + DomUtils::setBoolAttribute(de, "loop", loopInterpolation()); + return de; +} + +/*! Restores the KeyFrameInterpolator state from a \c QDomElement created by + domElement(). + + Note that the frame() pointer is not included in the domElement(): you need to + setFrame() after this method to attach a Frame to the KeyFrameInterpolator. + + See Vec::initFromDOMElement() for a complete code example. + + See also Camera::initFromDOMElement() and Frame::initFromDOMElement(). */ +CGAL_INLINE_FUNCTION +void KeyFrameInterpolator::initFromDOMElement(const QDomElement &element) { + qDeleteAll(keyFrame_); + keyFrame_.clear(); + QDomElement child = element.firstChild().toElement(); + while (!child.isNull()) { + if (child.tagName() == "KeyFrame") { + Frame fr; + fr.initFromDOMElement(child); + qreal time = DomUtils::qrealFromDom(child, "time", 0.0); + addKeyFrame(fr, time); + } + + child = child.nextSibling().toElement(); + } + + // #CONNECTION# Values cut pasted from constructor + setInterpolationTime(DomUtils::qrealFromDom(element, "time", 0.0)); + setInterpolationSpeed(DomUtils::qrealFromDom(element, "speed", 1.0)); + setInterpolationPeriod(DomUtils::intFromDom(element, "period", 40)); + setClosedPath(DomUtils::boolFromDom(element, "closedPath", false)); + setLoopInterpolation(DomUtils::boolFromDom(element, "loop", false)); + + // setFrame(NULL); + pathIsValid_ = false; + valuesAreValid_ = false; + currentFrameValid_ = false; + + stopInterpolation(); +} + +#ifndef DOXYGEN + +//////////// KeyFrame private class implementation ///////// +CGAL_INLINE_FUNCTION +KeyFrameInterpolator::KeyFrame::KeyFrame(const Frame &fr, qreal t) + : time_(t), frame_(NULL) { + p_ = fr.position(); + q_ = fr.orientation(); +} + +CGAL_INLINE_FUNCTION +KeyFrameInterpolator::KeyFrame::KeyFrame(const Frame *fr, qreal t) + : time_(t), frame_(fr) { + updateValuesFromPointer(); +} + +CGAL_INLINE_FUNCTION +void KeyFrameInterpolator::KeyFrame::updateValuesFromPointer() { + p_ = frame()->position(); + q_ = frame()->orientation(); +} + +CGAL_INLINE_FUNCTION +void KeyFrameInterpolator::KeyFrame::computeTangent( + const KeyFrame *const prev, const KeyFrame *const next) { + tgP_ = 0.5 * (next->position() - prev->position()); + tgQ_ = Quaternion::squadTangent(prev->orientation(), q_, next->orientation()); +} + +CGAL_INLINE_FUNCTION +void KeyFrameInterpolator::KeyFrame::flipOrientationIfNeeded( + const Quaternion &prev) { + if (Quaternion::dot(prev, q_) < 0.0) + q_.negate(); +} +#endif // DOXYGEN + +}} diff --git a/GraphicsView/include/CGAL/Qt/manipulatedCameraFrame.h b/GraphicsView/include/CGAL/Qt/manipulatedCameraFrame.h new file mode 100644 index 00000000000..77116b23788 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/manipulatedCameraFrame.h @@ -0,0 +1,257 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 + +#ifndef QGLVIEWER_MANIPULATED_CAMERA_FRAME_H +#define QGLVIEWER_MANIPULATED_CAMERA_FRAME_H +#include + +#include +#include +#include + +namespace CGAL{ +namespace qglviewer { +/*! \brief The ManipulatedCameraFrame class represents a ManipulatedFrame with + Camera specific mouse bindings. \class ManipulatedCameraFrame + manipulatedCameraFrame.h CGAL::QGLViewer/manipulatedCameraFrame.h + + A ManipulatedCameraFrame is a specialization of a ManipulatedFrame, designed + to be set as the Camera::frame(). Mouse motions are basically interpreted in a + negated way: when the mouse goes to the right, the ManipulatedFrame + translation goes to the right, while the ManipulatedCameraFrame has to go to + the \e left, so that the \e scene seems to move to the right. + + A ManipulatedCameraFrame rotates around its pivotPoint(), which corresponds to + the associated Camera::pivotPoint(). + + A ManipulatedCameraFrame can also "fly" in the scene. It basically moves + forward, and turns according to the mouse motion. See flySpeed(), + sceneUpVector() and the MOVE_FORWARD and MOVE_BACKWARD + MouseAction. + + See the mouse page for a description of the + possible actions that can be performed using the mouse and their bindings. + \nosubgrouping */ +class CGAL_QT_EXPORT ManipulatedCameraFrame : public ManipulatedFrame { +#ifndef DOXYGEN + friend class Camera; + friend class ::CGAL::QGLViewer; +#endif + + Q_OBJECT + +public: + ManipulatedCameraFrame(); + /*! Virtual destructor. Empty. */ + virtual ~ManipulatedCameraFrame() {} + + ManipulatedCameraFrame(const ManipulatedCameraFrame &mcf); + ManipulatedCameraFrame &operator=(const ManipulatedCameraFrame &mcf); + + /*! @name Pivot point */ + //@{ +public: + /*! Returns the point the ManipulatedCameraFrame pivot point, around which the + camera rotates. + + It is defined in the world coordinate system. Default value is (0,0,0). + + When the ManipulatedCameraFrame is associated to a Camera, + Camera::pivotPoint() also returns this value. This point can interactively be + changed using the mouse (see Camera::setPivotPointFromPixel() and + RAP_FROM_PIXEL and RAP_IS_CENTER in the mouse page). */ + Vec pivotPoint() const { return pivotPoint_; } + /*! Sets the pivotPoint(), defined in the world coordinate system. */ + void setPivotPoint(const Vec &point) { pivotPoint_ = point; } + + //@} + + /*! @name Camera manipulation */ + //@{ +public: + /*! Returns \c true when the frame's rotation is constrained around the + sceneUpVector(), and \c false otherwise, when the rotation is completely + free (default). + + In free mode, the associated camera can be arbitrarily rotated in the + scene, along its three axis, thus possibly leading to any arbitrary + orientation. + + When you setRotatesAroundUpVector() to \c true, the sceneUpVector() + defines a 'vertical' direction around which the camera rotates. The camera + can rotate left or right, around this axis. It can also be moved up or down + to show the 'top' and 'bottom' views of the scene. As a result, the + sceneUpVector() will always appear vertical in the scene, and the horizon + is preserved and stays projected along the camera's horizontal axis. + + Note that setting this value to \c true when the sceneUpVector() is + not already vertically projected will break these invariants. It will also + limit the possible movement of the camera, possibly up to a lock when the + sceneUpVector() is projected horizontally. Use Camera::setUpVector() to + define the sceneUpVector() and align the camera before calling this method + to ensure this does not happen. */ + bool rotatesAroundUpVector() const { return rotatesAroundUpVector_; } + /*! Sets the value of rotatesAroundUpVector(). + + Default value is false (free rotation). */ + void setRotatesAroundUpVector(bool constrained) { + rotatesAroundUpVector_ = constrained; + } + + /*! Returns whether or not the ZOOM action zooms on the pivot + point. + + When set to \c false (default), a zoom action will move the camera along its + Camera::viewDirection(), i.e. back and forth along a direction perpendicular + to the projection screen. + + setZoomsOnPivotPoint() to \c true will move the camera along an axis defined + by the Camera::pivotPoint() and its current position instead. As a result, + the projected position of the pivot point on screen will stay the same + during a zoom. */ + bool zoomsOnPivotPoint() const { return zoomsOnPivotPoint_; } + /*! Sets the value of zoomsOnPivotPoint(). + + Default value is false. */ + void setZoomsOnPivotPoint(bool enabled) { zoomsOnPivotPoint_ = enabled; } + +private: +#ifndef DOXYGEN + void zoom(qreal delta, const Camera *const camera); +#endif + //@} + + /*! @name Fly parameters */ + //@{ +public Q_SLOTS: + /*! Sets the flySpeed(), defined in OpenGL units. + + Default value is 0.0, but it is modified according to the + CGAL::QGLViewer::sceneRadius() when the ManipulatedCameraFrame is set as the + Camera::frame(). */ + void setFlySpeed(qreal speed) { flySpeed_ = speed; } + + /*! Sets the sceneUpVector(), defined in the world coordinate system. + + Default value is (0,1,0), but it is updated by the Camera when this object is + set as its Camera::frame(). Using Camera::setUpVector() instead is probably a + better solution. */ + void setSceneUpVector(const Vec &up) { sceneUpVector_ = up; } + +public: + /*! Returns the fly speed, expressed in OpenGL units. + + It corresponds to the incremental displacement that is periodically applied to + the ManipulatedCameraFrame position when a MOVE_FORWARD or + MOVE_BACKWARD MouseAction is proceeded. + + \attention When the ManipulatedCameraFrame is set as the Camera::frame(), this + value is set according to the CGAL::QGLViewer::sceneRadius() by + CGAL::QGLViewer::setSceneRadius(). */ + qreal flySpeed() const { return flySpeed_; } + + /*! Returns the up vector of the scene, expressed in the world coordinate + system. + + In 'fly mode' (corresponding to the MOVE_FORWARD and + MOVE_BACKWARD MouseAction bindings), horizontal + displacements of the mouse rotate the ManipulatedCameraFrame around this + vector. Vertical displacements rotate always around the Camera \c X axis. + + This value is also used when setRotationIsConstrained() is set to \c true to + define the up vector (and incidentally the 'horizon' plane) around which the + camera will rotate. + + Default value is (0,1,0), but it is updated by the Camera when this object is + set as its Camera::frame(). Camera::setOrientation() and + Camera::setUpVector()) direclty modify this value and should be used instead. +*/ + Vec sceneUpVector() const { return sceneUpVector_; } + +#ifndef DOXYGEN + Vec flyUpVector() const; + void setFlyUpVector(const Vec &up); +#endif + //@} + + /*! @name Mouse event handlers */ + //@{ +protected: + virtual void mouseReleaseEvent(QMouseEvent *const event, + Camera *const camera); + virtual void mouseMoveEvent(QMouseEvent *const event, Camera *const camera); + virtual void wheelEvent(QWheelEvent *const event, Camera *const camera); + //@} + + /*! @name Spinning */ + //@{ +protected Q_SLOTS: + virtual void spin(); + //@} + + /*! @name XML representation */ + //@{ +public: + virtual QDomElement domElement(const QString &name, + QDomDocument &document) const; +public Q_SLOTS: + virtual void initFromDOMElement(const QDomElement &element); +//@} + +#ifndef DOXYGEN +protected: + virtual void startAction( + int ma, + bool withConstraint = true); // int is really a MouseAction +#endif + +private Q_SLOTS: + virtual void flyUpdate(); + +private: + void updateSceneUpVector(); + Quaternion turnQuaternion(int x, const Camera *const camera); + Quaternion pitchYawQuaternion(int x, int y, const Camera *const camera); + +private: + // Fly mode data + qreal flySpeed_; + qreal driveSpeed_; + Vec sceneUpVector_; + QTimer flyTimer_; + + bool rotatesAroundUpVector_; + // Inverse the direction of an horizontal mouse motion. Depends on the + // projected screen orientation of the vertical axis when the mouse button is + // pressed. + bool constrainedRotationIsReversed_; + + bool zoomsOnPivotPoint_; + + Vec pivotPoint_; +}; + +}} // namespace CGAL::qglviewer + +#ifdef CGAL_HEADER_ONLY +//#include +#endif // CGAL_HEADER_ONLY +#endif // QGLVIEWER_MANIPULATED_CAMERA_FRAME_H diff --git a/GraphicsView/include/CGAL/Qt/manipulatedCameraFrame_impl.h b/GraphicsView/include/CGAL/Qt/manipulatedCameraFrame_impl.h new file mode 100644 index 00000000000..0f9c76e0d58 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/manipulatedCameraFrame_impl.h @@ -0,0 +1,488 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 + +#ifdef CGAL_HEADER_ONLY +#define CGAL_INLINE_FUNCTION inline + +#include + +#else +#define CGAL_INLINE_FUNCTION +#endif +#include +#include +#include +#include +#include + +#include + +namespace CGAL{ +namespace qglviewer{ + +/*! Default constructor. + + flySpeed() is set to 0.0 and sceneUpVector() is (0,1,0). The pivotPoint() is + set to (0,0,0). + + \attention Created object is removeFromMouseGrabberPool(). */ +CGAL_INLINE_FUNCTION +ManipulatedCameraFrame::ManipulatedCameraFrame() + : driveSpeed_(0.0), sceneUpVector_(0.0, 1.0, 0.0), + rotatesAroundUpVector_(false), zoomsOnPivotPoint_(false) { + setFlySpeed(0.0); + removeFromMouseGrabberPool(); + connect(&flyTimer_, SIGNAL(timeout()), SLOT(flyUpdate())); +} + +/*! Equal operator. Calls ManipulatedFrame::operator=() and then copy + * attributes. */ +CGAL_INLINE_FUNCTION +ManipulatedCameraFrame &ManipulatedCameraFrame:: +operator=(const ManipulatedCameraFrame &mcf) { + ManipulatedFrame::operator=(mcf); + + setFlySpeed(mcf.flySpeed()); + setSceneUpVector(mcf.sceneUpVector()); + setRotatesAroundUpVector(mcf.rotatesAroundUpVector_); + setZoomsOnPivotPoint(mcf.zoomsOnPivotPoint_); + + return *this; +} + +/*! Copy constructor. Performs a deep copy of all members using operator=(). */ +CGAL_INLINE_FUNCTION +ManipulatedCameraFrame::ManipulatedCameraFrame( + const ManipulatedCameraFrame &mcf) + : ManipulatedFrame(mcf) { + removeFromMouseGrabberPool(); + connect(&flyTimer_, SIGNAL(timeout()), SLOT(flyUpdate())); + (*this) = (mcf); +} + +//////////////////////////////////////////////////////////////////////////////// + +/*! Overloading of ManipulatedFrame::spin(). + +Rotates the ManipulatedCameraFrame around its pivotPoint() instead of its +origin. */ +CGAL_INLINE_FUNCTION +void ManipulatedCameraFrame::spin() { + rotateAroundPoint(spinningQuaternion(), pivotPoint()); +} + +#ifndef DOXYGEN +/*! Called for continuous frame motion in fly mode (see + MOVE_FORWARD). Emits manipulated(). */ +CGAL_INLINE_FUNCTION +void ManipulatedCameraFrame::flyUpdate() { + static Vec flyDisp(0.0, 0.0, 0.0); + switch (action_) { + case MOVE_FORWARD: + flyDisp.z = -flySpeed(); + translate(localInverseTransformOf(flyDisp)); + break; + case MOVE_BACKWARD: + flyDisp.z = flySpeed(); + translate(localInverseTransformOf(flyDisp)); + break; + case DRIVE: + flyDisp.z = flySpeed() * driveSpeed_; + translate(localInverseTransformOf(flyDisp)); + break; + default: + break; + } + + // Needs to be out of the switch since ZOOM/fastDraw()/wheelEvent use this + // callback to trigger a final draw(). #CONNECTION# wheelEvent. + Q_EMIT manipulated(); +} +#endif + +/*! This method will be called by the Camera when its orientation is changed, so +that the sceneUpVector (private) is changed accordingly. You should not need to +call this method. */ +CGAL_INLINE_FUNCTION +void ManipulatedCameraFrame::updateSceneUpVector() { + sceneUpVector_ = inverseTransformOf(Vec(0.0, 1.0, 0.0)); +} + +//////////////////////////////////////////////////////////////////////////////// +// S t a t e s a v i n g a n d r e s t o r i n g // +//////////////////////////////////////////////////////////////////////////////// + +/*! Returns an XML \c QDomElement that represents the ManipulatedCameraFrame. + + Adds to the ManipulatedFrame::domElement() the ManipulatedCameraFrame specific + informations in a \c ManipulatedCameraParameters child QDomElement. + + \p name is the name of the QDomElement tag. \p doc is the \c QDomDocument + factory used to create QDomElement. + + Use initFromDOMElement() to restore the ManipulatedCameraFrame state from the + resulting \c QDomElement. + + See Vec::domElement() for a complete example. See also + Quaternion::domElement(), Frame::domElement(), Camera::domElement()... */ +CGAL_INLINE_FUNCTION +QDomElement ManipulatedCameraFrame::domElement(const QString &name, + QDomDocument &document) const { + QDomElement e = ManipulatedFrame::domElement(name, document); + QDomElement mcp = document.createElement("ManipulatedCameraParameters"); + mcp.setAttribute("flySpeed", QString::number(flySpeed())); + DomUtils::setBoolAttribute(mcp, "rotatesAroundUpVector", + rotatesAroundUpVector()); + DomUtils::setBoolAttribute(mcp, "zoomsOnPivotPoint", zoomsOnPivotPoint()); + mcp.appendChild(sceneUpVector().domElement("sceneUpVector", document)); + e.appendChild(mcp); + return e; +} + +/*! Restores the ManipulatedCameraFrame state from a \c QDomElement created by +domElement(). + +First calls ManipulatedFrame::initFromDOMElement() and then initializes +ManipulatedCameraFrame specific parameters. */ +CGAL_INLINE_FUNCTION +void ManipulatedCameraFrame::initFromDOMElement(const QDomElement &element) { + // No need to initialize, since default sceneUpVector and flySpeed are not + // meaningful. It's better to keep current ones. And it would destroy + // constraint() and referenceFrame(). *this = ManipulatedCameraFrame(); + ManipulatedFrame::initFromDOMElement(element); + + QDomElement child = element.firstChild().toElement(); + while (!child.isNull()) { + if (child.tagName() == "ManipulatedCameraParameters") { + setFlySpeed(DomUtils::qrealFromDom(child, "flySpeed", flySpeed())); + setRotatesAroundUpVector( + DomUtils::boolFromDom(child, "rotatesAroundUpVector", false)); + setZoomsOnPivotPoint( + DomUtils::boolFromDom(child, "zoomsOnPivotPoint", false)); + + QDomElement schild = child.firstChild().toElement(); + while (!schild.isNull()) { + if (schild.tagName() == "sceneUpVector") + setSceneUpVector(Vec(schild)); + + schild = schild.nextSibling().toElement(); + } + } + child = child.nextSibling().toElement(); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// M o u s e h a n d l i n g // +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DOXYGEN +/*! Protected internal method used to handle mouse events. */ +CGAL_INLINE_FUNCTION +void ManipulatedCameraFrame::startAction(int ma, bool withConstraint) { + ManipulatedFrame::startAction(ma, withConstraint); + + switch (action_) { + case MOVE_FORWARD: + case MOVE_BACKWARD: + case DRIVE: + flyTimer_.setSingleShot(false); + flyTimer_.start(10); + break; + case ROTATE: + constrainedRotationIsReversed_ = transformOf(sceneUpVector_).y < 0.0; + break; + default: + break; + } +} + +CGAL_INLINE_FUNCTION +void ManipulatedCameraFrame::zoom(qreal delta, const Camera *const camera) { + const qreal sceneRadius = camera->sceneRadius(); + if (zoomsOnPivotPoint_) { + Vec direction = position() - camera->pivotPoint(); + if (direction.norm() > 0.02 * sceneRadius || delta > 0.0) + translate(delta * direction); + } else { + const qreal coef = + qMax(fabs((camera->frame()->coordinatesOf(camera->pivotPoint())).z), + qreal(0.2) * sceneRadius); + Vec trans(0.0, 0.0, -coef * delta); + translate(inverseTransformOf(trans)); + } +} + +#endif + +/*! Overloading of ManipulatedFrame::mouseMoveEvent(). + +Motion depends on mouse binding (see mouse page for +details). The resulting displacements are basically inverted from those of a +ManipulatedFrame. */ +CGAL_INLINE_FUNCTION +void ManipulatedCameraFrame::mouseMoveEvent(QMouseEvent *const event, + Camera *const camera) { + // #CONNECTION# mouseMoveEvent does the update(). + switch (action_) { + case TRANSLATE: { + const QPoint delta = prevPos_ - event->pos(); + Vec trans(delta.x(), -delta.y(), 0.0); + // Scale to fit the screen mouse displacement + switch (camera->type()) { + case Camera::PERSPECTIVE: + trans *= 2.0 * tan(camera->fieldOfView() / 2.0) * + fabs((camera->frame()->coordinatesOf(pivotPoint())).z) / + camera->screenHeight(); + break; + case Camera::ORTHOGRAPHIC: { + GLdouble w, h; + camera->getOrthoWidthHeight(w, h); + trans[0] *= 2.0 * w / camera->screenWidth(); + trans[1] *= 2.0 * h / camera->screenHeight(); + break; + } + } + translate(inverseTransformOf(translationSensitivity() * trans)); + break; + } + + case MOVE_FORWARD: { + Quaternion rot = pitchYawQuaternion(event->x(), event->y(), camera); + rotate(rot); + //#CONNECTION# wheelEvent MOVE_FORWARD case + // actual translation is made in flyUpdate(). + // translate(inverseTransformOf(Vec(0.0, 0.0, -flySpeed()))); + break; + } + + case MOVE_BACKWARD: { + Quaternion rot = pitchYawQuaternion(event->x(), event->y(), camera); + rotate(rot); + // actual translation is made in flyUpdate(). + // translate(inverseTransformOf(Vec(0.0, 0.0, flySpeed()))); + break; + } + + case DRIVE: { + Quaternion rot = turnQuaternion(event->x(), camera); + rotate(rot); + // actual translation is made in flyUpdate(). + driveSpeed_ = 0.01 * (event->y() - pressPos_.y()); + break; + } + + case ZOOM: { + zoom(deltaWithPrevPos(event, camera), camera); + break; + } + + case LOOK_AROUND: { + Quaternion rot = pitchYawQuaternion(event->x(), event->y(), camera); + rotate(rot); + break; + } + + case ROTATE: { + Quaternion rot; + if (rotatesAroundUpVector_) { + // Multiply by 2.0 to get on average about the same speed as with the + // deformed ball + qreal dx = 2.0 * rotationSensitivity() * (prevPos_.x() - event->x()) / + camera->screenWidth(); + qreal dy = 2.0 * rotationSensitivity() * (prevPos_.y() - event->y()) / + camera->screenHeight(); + if (constrainedRotationIsReversed_) + dx = -dx; + Vec verticalAxis = transformOf(sceneUpVector_); + rot = Quaternion(verticalAxis, dx) * Quaternion(Vec(1.0, 0.0, 0.0), dy); + } else { + Vec trans = camera->projectedCoordinatesOf(pivotPoint()); + rot = deformedBallQuaternion(event->x(), event->y(), trans[0], trans[1], + camera); + } + //#CONNECTION# These two methods should go together (spinning detection and + // activation) + computeMouseSpeed(event); + setSpinningQuaternion(rot); + spin(); + break; + } + + case SCREEN_ROTATE: { + Vec trans = camera->projectedCoordinatesOf(pivotPoint()); + + const qreal angle = atan2(event->y() - trans[1], event->x() - trans[0]) - + atan2(prevPos_.y() - trans[1], prevPos_.x() - trans[0]); + + Quaternion rot(Vec(0.0, 0.0, 1.0), angle); + //#CONNECTION# These two methods should go together (spinning detection and + // activation) + computeMouseSpeed(event); + setSpinningQuaternion(rot); + spin(); + updateSceneUpVector(); + break; + } + + case ROLL: { + const qreal angle = + CGAL_PI * (event->x() - prevPos_.x()) / camera->screenWidth(); + Quaternion rot(Vec(0.0, 0.0, 1.0), angle); + rotate(rot); + setSpinningQuaternion(rot); + updateSceneUpVector(); + break; + } + + case SCREEN_TRANSLATE: { + Vec trans; + int dir = mouseOriginalDirection(event); + if (dir == 1) + trans.setValue(prevPos_.x() - event->x(), 0.0, 0.0); + else if (dir == -1) + trans.setValue(0.0, event->y() - prevPos_.y(), 0.0); + + switch (camera->type()) { + case Camera::PERSPECTIVE: + trans *= 2.0 * tan(camera->fieldOfView() / 2.0) * + fabs((camera->frame()->coordinatesOf(pivotPoint())).z) / + camera->screenHeight(); + break; + case Camera::ORTHOGRAPHIC: { + GLdouble w, h; + camera->getOrthoWidthHeight(w, h); + trans[0] *= 2.0 * w / camera->screenWidth(); + trans[1] *= 2.0 * h / camera->screenHeight(); + break; + } + } + + translate(inverseTransformOf(translationSensitivity() * trans)); + break; + } + + case ZOOM_ON_REGION: + case NO_MOUSE_ACTION: + break; + } + + if (action_ != NO_MOUSE_ACTION) { + prevPos_ = event->pos(); + if (action_ != ZOOM_ON_REGION) + // ZOOM_ON_REGION should not emit manipulated(). + // prevPos_ is used to draw rectangle feedback. + Q_EMIT manipulated(); + } +} + +/*! This is an overload of ManipulatedFrame::mouseReleaseEvent(). The + MouseAction is terminated. */ +CGAL_INLINE_FUNCTION +void ManipulatedCameraFrame::mouseReleaseEvent(QMouseEvent *const event, + Camera *const camera) { + if ((action_ == MOVE_FORWARD) || + (action_ == MOVE_BACKWARD) || (action_ == DRIVE)) + flyTimer_.stop(); + + if (action_ == ZOOM_ON_REGION) + camera->fitScreenRegion(QRect(pressPos_, event->pos())); + + ManipulatedFrame::mouseReleaseEvent(event, camera); +} + +/*! This is an overload of ManipulatedFrame::wheelEvent(). + +The wheel behavior depends on the wheel binded action. Current possible actions +are ZOOM, MOVE_FORWARD, MOVE_BACKWARD. +ZOOM speed depends on wheelSensitivity() while +MOVE_FORWARD and MOVE_BACKWARD depend on flySpeed(). See +CGAL::QGLViewer::setWheelBinding() to customize the binding. */ +CGAL_INLINE_FUNCTION +void ManipulatedCameraFrame::wheelEvent(QWheelEvent *const event, + Camera *const camera) { + //#CONNECTION# CGAL::QGLViewer::setWheelBinding, ManipulatedFrame::wheelEvent. + switch (action_) { + case ZOOM: { + zoom(wheelDelta(event), camera); + Q_EMIT manipulated(); + break; + } + case MOVE_FORWARD: + case MOVE_BACKWARD: + //#CONNECTION# mouseMoveEvent() MOVE_FORWARD case + translate( + inverseTransformOf(Vec(0.0, 0.0, 0.2 * flySpeed() * event->delta()))); + Q_EMIT manipulated(); + break; + default: + break; + } + + // #CONNECTION# startAction should always be called before + if (previousConstraint_) + setConstraint(previousConstraint_); + + // The wheel triggers a fastDraw. A final update() is needed after the last + // wheel event to polish the rendering using draw(). Since the last wheel + // event does not say its name, we use the flyTimer_ to trigger flyUpdate(), + // which emits manipulated. Two wheel events separated by more than this delay + // milliseconds will trigger a draw(). + const int finalDrawAfterWheelEventDelay = 400; + + // Starts (or prolungates) the timer. + flyTimer_.setSingleShot(true); + flyTimer_.start(finalDrawAfterWheelEventDelay); + + // This could also be done *before* manipulated is emitted, so that + // isManipulated() returns false. But then fastDraw would not be used with + // wheel. Detecting the last wheel event and forcing a final draw() is done + // using the timer_. + action_ = NO_MOUSE_ACTION; +} + +//////////////////////////////////////////////////////////////////////////////// + +/*! Returns a Quaternion that is a rotation around current camera Y, + * proportionnal to the horizontal mouse position. */ +CGAL_INLINE_FUNCTION +Quaternion ManipulatedCameraFrame::turnQuaternion(int x, + const Camera *const camera) { + return Quaternion(Vec(0.0, 1.0, 0.0), rotationSensitivity() * + (prevPos_.x() - x) / + camera->screenWidth()); +} + +/*! Returns a Quaternion that is the composition of two rotations, inferred from + the mouse pitch (X axis) and yaw (sceneUpVector() axis). */ +Quaternion +CGAL_INLINE_FUNCTION +ManipulatedCameraFrame::pitchYawQuaternion(int x, int y, + const Camera *const camera) { + const Quaternion rotX(Vec(1.0, 0.0, 0.0), rotationSensitivity() * + (prevPos_.y() - y) / + camera->screenHeight()); + const Quaternion rotY(transformOf(sceneUpVector()), + rotationSensitivity() * (prevPos_.x() - x) / + camera->screenWidth()); + return rotY * rotX; +} + +}} diff --git a/GraphicsView/include/CGAL/Qt/manipulatedFrame.h b/GraphicsView/include/CGAL/Qt/manipulatedFrame.h new file mode 100644 index 00000000000..ca3102713ee --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/manipulatedFrame.h @@ -0,0 +1,379 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 + +#ifndef QGLVIEWER_MANIPULATED_FRAME_H +#define QGLVIEWER_MANIPULATED_FRAME_H +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace CGAL{ +namespace qglviewer { + +/*! \brief A ManipulatedFrame is a Frame that can be rotated and translated + using the mouse. \class ManipulatedFrame manipulatedFrame.h + CGAL::QGLViewer/manipulatedFrame.h + + It converts the mouse motion into a translation and an orientation updates. A + ManipulatedFrame is used to move an object in the scene. Combined with object + selection, its MouseGrabber properties and a dynamic update of the scene, the + ManipulatedFrame introduces a great reactivity in your applications. + + A ManipulatedFrame is attached to a CGAL::QGLViewer using + CGAL::QGLViewer::setManipulatedFrame(): \code init() { setManipulatedFrame( new + ManipulatedFrame() ); } + + draw() + { + glPushMatrix(); + glMultMatrixd(manipulatedFrame()->matrix()); + // draw the manipulated object here + glPopMatrix(); + } + \endcode + See the manipulatedFrame + example for a complete application. + + Mouse events are normally sent to the CGAL::QGLViewer::camera(). You have to press + the CGAL::QGLViewer::FRAME state key (default is \c Control) to move the + CGAL::QGLViewer::manipulatedFrame() instead. See the mouse + page for a description of mouse button bindings. + +

Inherited functionalities

+ + A ManipulatedFrame is an overloaded instance of a Frame. The powerful + coordinate system transformation functions (Frame::coordinatesOf(), + Frame::transformOf(), ...) can hence be applied to a ManipulatedFrame. + + A ManipulatedFrame is also a MouseGrabber. If the mouse cursor gets within a + distance of 10 pixels from the projected position of the ManipulatedFrame, the + ManipulatedFrame becomes the new CGAL::QGLViewer::mouseGrabber(). It can then be + manipulated directly, without any specific state key, object selection or GUI + intervention. This is very convenient to directly move some objects in the + scene (typically a light). See the mouseGrabber example as an + illustration. Note that QWidget::setMouseTracking() needs to be enabled in + order to use this feature (see the MouseGrabber documentation). + +

Advanced functionalities

+ + A CGAL::QGLViewer can handle at most one ManipulatedFrame at a time. If you want to + move several objects in the scene, you simply have to keep a list of the + different ManipulatedFrames, and to activate the right one (using + CGAL::QGLViewer::setManipulatedFrame()) when needed. This can for instance be done + according to an object selection: see the luxo + example for an illustration. + + When the ManipulatedFrame is being manipulated using the mouse (mouse pressed + and not yet released), isManipulated() returns \c true. This might be used to + trigger a specific action or display (as is done with CGAL::QGLViewer::fastDraw()). + + The ManipulatedFrame also emits a manipulated() signal each time its state is + modified by the mouse. This signal is automatically connected to the + CGAL::QGLViewer::update() slot when the ManipulatedFrame is attached to a viewer + using CGAL::QGLViewer::setManipulatedFrame(). + + You can make the ManipulatedFrame spin() if you release the rotation mouse + button while moving the mouse fast enough (see spinningSensitivity()). See + also translationSensitivity() and rotationSensitivity() for sensitivity + tuning. \nosubgrouping */ +class CGAL_QT_EXPORT ManipulatedFrame : public Frame, public MouseGrabber { +#ifndef DOXYGEN + friend class Camera; + friend class ::CGAL::QGLViewer; +#endif + + Q_OBJECT + +public: + ManipulatedFrame(); + /*! Virtual destructor. Empty. */ + virtual ~ManipulatedFrame() {} + + ManipulatedFrame(const ManipulatedFrame &mf); + ManipulatedFrame &operator=(const ManipulatedFrame &mf); + +Q_SIGNALS: + /*! This signal is emitted when ever the ManipulatedFrame is manipulated (i.e. + rotated or translated) using the mouse. Connect this signal to any object that + should be notified. + + Note that this signal is automatically connected to the CGAL::QGLViewer::update() + slot, when the ManipulatedFrame is attached to a viewer using + CGAL::QGLViewer::setManipulatedFrame(), which is probably all you need. + + Use the CGAL::QGLViewer::QGLViewerPool() if you need to connect this signal to all + the viewers. + + See also the spun(), modified(), interpolated() and + KeyFrameInterpolator::interpolated() signals' documentations. */ + void manipulated(); + + /*! This signal is emitted when the ManipulatedFrame isSpinning(). + + Note that for the CGAL::QGLViewer::manipulatedFrame(), this signal is automatically + connected to the CGAL::QGLViewer::update() slot. + + Connect this signal to any object that should be notified. Use the + CGAL::QGLViewer::QGLViewerPool() if you need to connect this signal to all the + viewers. + + See also the manipulated(), modified(), interpolated() and + KeyFrameInterpolator::interpolated() signals' documentations. */ + void spun(); + + /*! @name Manipulation sensitivity */ + //@{ +public Q_SLOTS: + /*! Defines the rotationSensitivity(). */ + void setRotationSensitivity(qreal sensitivity) { + rotationSensitivity_ = sensitivity; + } + /*! Defines the translationSensitivity(). */ + void setTranslationSensitivity(qreal sensitivity) { + translationSensitivity_ = sensitivity; + } + /*! Defines the spinningSensitivity(), in pixels per milliseconds. */ + void setSpinningSensitivity(qreal sensitivity) { + spinningSensitivity_ = sensitivity; + } + /*! Defines the wheelSensitivity(). */ + void setWheelSensitivity(qreal sensitivity) { + wheelSensitivity_ = sensitivity; + } + /*! Defines the zoomSensitivity(). */ + void setZoomSensitivity(qreal sensitivity) { zoomSensitivity_ = sensitivity; } + +public: + /*! Returns the influence of a mouse displacement on the ManipulatedFrame + rotation. + + Default value is 1.0. With an identical mouse displacement, a higher value + will generate a larger rotation (and inversely for lower values). A 0.0 value + will forbid ManipulatedFrame mouse rotation (see also constraint()). + + See also setRotationSensitivity(), translationSensitivity(), + spinningSensitivity() and wheelSensitivity(). */ + qreal rotationSensitivity() const { return rotationSensitivity_; } + /*! Returns the influence of a mouse displacement on the ManipulatedFrame + translation. + + Default value is 1.0. You should not have to modify this value, since with 1.0 + the ManipulatedFrame precisely stays under the mouse cursor. + + With an identical mouse displacement, a higher value will generate a larger + translation (and inversely for lower values). A 0.0 value will forbid + ManipulatedFrame mouse translation (see also constraint()). + + \note When the ManipulatedFrame is used to move a \e Camera (see the + ManipulatedCameraFrame class documentation), after zooming on a small region + of your scene, the camera may translate too fast. For a camera, it is the + Camera::pivotPoint() that exactly matches the mouse displacement. Hence, + instead of changing the translationSensitivity(), solve the problem by + (temporarily) setting the Camera::pivotPoint() to a point on the zoomed region + (see the CGAL::QGLViewer::RAP_FROM_PIXEL mouse binding in the mouse page). + + See also setTranslationSensitivity(), rotationSensitivity(), + spinningSensitivity() and wheelSensitivity(). */ + qreal translationSensitivity() const { return translationSensitivity_; } + /*! Returns the minimum mouse speed required (at button release) to make the + ManipulatedFrame spin(). + + See spin(), spinningQuaternion() and startSpinning() for details. + + Mouse speed is expressed in pixels per milliseconds. Default value is 0.3 (300 + pixels per second). Use setSpinningSensitivity() to tune this value. A higher + value will make spinning more difficult (a value of 100.0 forbids spinning in + practice). + + See also setSpinningSensitivity(), translationSensitivity(), + rotationSensitivity() and wheelSensitivity(). */ + qreal spinningSensitivity() const { return spinningSensitivity_; } + + /*! Returns the zoom sensitivity. + + Default value is 1.0. A higher value will make the zoom faster. + Use a negative value to invert the zoom in and out directions. + + See also setZoomSensitivity(), translationSensitivity(), rotationSensitivity() + wheelSensitivity() and spinningSensitivity(). */ + qreal zoomSensitivity() const { return zoomSensitivity_; } + /*! Returns the mouse wheel sensitivity. + + Default value is 1.0. A higher value will make the wheel action more efficient + (usually meaning a faster zoom). Use a negative value to invert the zoom in + and out directions. + + See also setWheelSensitivity(), translationSensitivity(), + rotationSensitivity() zoomSensitivity() and spinningSensitivity(). */ + qreal wheelSensitivity() const { return wheelSensitivity_; } + //@} + + /*! @name Spinning */ + //@{ +public: + /*! Returns \c true when the ManipulatedFrame is spinning. + + During spinning, spin() rotates the ManipulatedFrame by its + spinningQuaternion() at a frequency defined when the ManipulatedFrame + startSpinning(). + + Use startSpinning() and stopSpinning() to change this state. Default value is + \c false. */ + bool isSpinning() const { return isSpinning_; } + /*! Returns the incremental rotation that is applied by spin() to the + ManipulatedFrame orientation when it isSpinning(). + + Default value is a null rotation (identity Quaternion). Use + setSpinningQuaternion() to change this value. + + The spinningQuaternion() axis is defined in the ManipulatedFrame coordinate + system. You can use Frame::transformOfFrom() to convert this axis from an + other Frame coordinate system. */ + Quaternion spinningQuaternion() const { return spinningQuaternion_; } +public Q_SLOTS: + /*! Defines the spinningQuaternion(). Its axis is defined in the + ManipulatedFrame coordinate system. */ + void setSpinningQuaternion(const Quaternion &spinningQuaternion) { + spinningQuaternion_ = spinningQuaternion; + } + virtual void startSpinning(int updateInterval); + /*! Stops the spinning motion started using startSpinning(). isSpinning() will + return \c false after this call. */ + virtual void stopSpinning() { + spinningTimer_.stop(); + isSpinning_ = false; + } +protected Q_SLOTS: + virtual void spin(); +private Q_SLOTS: + void spinUpdate(); + //@} + + /*! @name Mouse event handlers */ + //@{ +protected: + virtual void mousePressEvent(QMouseEvent *const event, Camera *const camera); + virtual void mouseMoveEvent(QMouseEvent *const event, Camera *const camera); + virtual void mouseReleaseEvent(QMouseEvent *const event, + Camera *const camera); + virtual void mouseDoubleClickEvent(QMouseEvent *const event, + Camera *const camera); + virtual void wheelEvent(QWheelEvent *const event, Camera *const camera); + //@} + +public: + /*! @name Current state */ + //@{ + bool isManipulated() const; + /*! Returns the \c MouseAction currently applied to this ManipulatedFrame. + + Will return CGAL::QGLViewer::NO_MOUSE_ACTION unless a mouse button is being + pressed and has been bound to this CGAL::QGLViewer::MouseHandler. + + The binding between mouse buttons and key modifiers and MouseAction is set + using CGAL::QGLViewer::setMouseBinding(Qt::Key key, Qt::KeyboardModifiers + modifiers, Qt::MouseButton buttons, MouseHandler handler, MouseAction action, + bool withConstraint). + */ + MouseAction currentMouseAction() const { return action_; } + //@} + + /*! @name MouseGrabber implementation */ + //@{ +public: + virtual void checkIfGrabsMouse(int x, int y, const Camera *const camera); + //@} + + /*! @name XML representation */ + //@{ +public: + virtual QDomElement domElement(const QString &name, + QDomDocument &document) const; +public Q_SLOTS: + virtual void initFromDOMElement(const QDomElement &element); +//@} + +#ifndef DOXYGEN +protected: + Quaternion deformedBallQuaternion(int x, int y, qreal cx, qreal cy, + const Camera *const camera); + + MouseAction action_; + Constraint *previousConstraint_; // When manipulation is without Contraint. + + virtual void startAction( + int ma, + bool withConstraint = true); // int is really a MouseAction + void computeMouseSpeed(const QMouseEvent *const e); + int mouseOriginalDirection(const QMouseEvent *const e); + + /*! Returns a screen scaled delta from event's position to prevPos_, along the + X or Y direction, whichever has the largest magnitude. */ + qreal deltaWithPrevPos(QMouseEvent *const event, Camera *const camera) const; + /*! Returns a normalized wheel delta, proportionnal to wheelSensitivity(). */ + qreal wheelDelta(const QWheelEvent *event) const; + + // Previous mouse position (used for incremental updates) and mouse press + // position. + QPoint prevPos_, pressPos_; + +private: + void zoom(qreal delta, const Camera *const camera); + +#endif // DOXYGEN + +private: + // Sensitivity + qreal rotationSensitivity_; + qreal translationSensitivity_; + qreal spinningSensitivity_; + qreal wheelSensitivity_; + qreal zoomSensitivity_; + + // Mouse speed and spinning + QTime last_move_time; + qreal mouseSpeed_; + int delay_; + bool isSpinning_; + QTimer spinningTimer_; + Quaternion spinningQuaternion_; + + // Whether the SCREEN_TRANS direction (horizontal or vertical) is fixed or + // not. + bool dirIsFixed_; + + // MouseGrabber + bool keepsGrabbingMouse_; +}; + +}} // namespace CGAL::qglviewer + +#ifdef CGAL_HEADER_ONLY +//#include +#endif // CGAL_HEADER_ONLY +#endif // QGLVIEWER_MANIPULATED_FRAME_H diff --git a/GraphicsView/include/CGAL/Qt/manipulatedFrame_impl.h b/GraphicsView/include/CGAL/Qt/manipulatedFrame_impl.h new file mode 100644 index 00000000000..e8ded238fa0 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/manipulatedFrame_impl.h @@ -0,0 +1,592 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 + +#ifdef CGAL_HEADER_ONLY +#define CGAL_INLINE_FUNCTION inline + +#include + +#else +#define CGAL_INLINE_FUNCTION +#endif + +#include +#include +#include +#include + +#include + +#include + +namespace CGAL{ +namespace qglviewer{ + + +/*! Default constructor. + + The translation is set to (0,0,0), with an identity rotation (0,0,0,1) (see + Frame constructor for details). + + The different sensitivities are set to their default values (see + rotationSensitivity(), translationSensitivity(), spinningSensitivity() and + wheelSensitivity()). */ +CGAL_INLINE_FUNCTION +ManipulatedFrame::ManipulatedFrame() + : action_(NO_MOUSE_ACTION), keepsGrabbingMouse_(false) { + // #CONNECTION# initFromDOMElement and accessor docs + setRotationSensitivity(1.0); + setTranslationSensitivity(1.0); + setSpinningSensitivity(0.3); + setWheelSensitivity(1.0); + setZoomSensitivity(1.0); + + isSpinning_ = false; + previousConstraint_ = NULL; + + connect(&spinningTimer_, SIGNAL(timeout()), SLOT(spinUpdate())); +} + +/*! Equal operator. Calls Frame::operator=() and then copy attributes. */ +CGAL_INLINE_FUNCTION +ManipulatedFrame &ManipulatedFrame::operator=(const ManipulatedFrame &mf) { + Frame::operator=(mf); + + setRotationSensitivity(mf.rotationSensitivity()); + setTranslationSensitivity(mf.translationSensitivity()); + setSpinningSensitivity(mf.spinningSensitivity()); + setWheelSensitivity(mf.wheelSensitivity()); + setZoomSensitivity(mf.zoomSensitivity()); + + mouseSpeed_ = 0.0; + dirIsFixed_ = false; + keepsGrabbingMouse_ = false; + action_ = NO_MOUSE_ACTION; + + return *this; +} + +/*! Copy constructor. Performs a deep copy of all attributes using operator=(). + */ +CGAL_INLINE_FUNCTION +ManipulatedFrame::ManipulatedFrame(const ManipulatedFrame &mf) + : Frame(mf), MouseGrabber() { + (*this) = mf; +} + +//////////////////////////////////////////////////////////////////////////////// + +/*! Implementation of the MouseGrabber main method. + +The ManipulatedFrame grabsMouse() when the mouse is within a 10 pixels region +around its Camera::projectedCoordinatesOf() position(). + +See the mouseGrabber example for an +illustration. */ +CGAL_INLINE_FUNCTION +void ManipulatedFrame::checkIfGrabsMouse(int x, int y, + const Camera *const camera) { + const int thresold = 10; + const Vec proj = camera->projectedCoordinatesOf(position()); + setGrabsMouse(keepsGrabbingMouse_ || ((fabs(x - proj.x) < thresold) && + (fabs(y - proj.y) < thresold))); +} + +//////////////////////////////////////////////////////////////////////////////// +// S t a t e s a v i n g a n d r e s t o r i n g // +//////////////////////////////////////////////////////////////////////////////// + +/*! Returns an XML \c QDomElement that represents the ManipulatedFrame. + + Adds to the Frame::domElement() the ManipulatedFrame specific informations in a + \c ManipulatedParameters child QDomElement. + + \p name is the name of the QDomElement tag. \p doc is the \c QDomDocument + factory used to create QDomElement. + + Use initFromDOMElement() to restore the ManipulatedFrame state from the + resulting \c QDomElement. + + See Vec::domElement() for a complete example. See also + Quaternion::domElement(), Camera::domElement()... */ +CGAL_INLINE_FUNCTION +QDomElement ManipulatedFrame::domElement(const QString &name, + QDomDocument &document) const { + QDomElement e = Frame::domElement(name, document); + QDomElement mp = document.createElement("ManipulatedParameters"); + mp.setAttribute("rotSens", QString::number(rotationSensitivity())); + mp.setAttribute("transSens", QString::number(translationSensitivity())); + mp.setAttribute("spinSens", QString::number(spinningSensitivity())); + mp.setAttribute("wheelSens", QString::number(wheelSensitivity())); + mp.setAttribute("zoomSens", QString::number(zoomSensitivity())); + e.appendChild(mp); + return e; +} + +/*! Restores the ManipulatedFrame state from a \c QDomElement created by +domElement(). + +Fields that are not described in \p element are set to their default values (see +ManipulatedFrame()). + +First calls Frame::initFromDOMElement() and then initializes ManipulatedFrame +specific parameters. Note that constraint() and referenceFrame() are not +restored and are left unchanged. + + +See Vec::initFromDOMElement() for a complete code example. */ +CGAL_INLINE_FUNCTION +void ManipulatedFrame::initFromDOMElement(const QDomElement &element) { + // Not called since it would set constraint() and referenceFrame() to NULL. + // *this = ManipulatedFrame(); + Frame::initFromDOMElement(element); + + stopSpinning(); + + QDomElement child = element.firstChild().toElement(); + while (!child.isNull()) { + if (child.tagName() == "ManipulatedParameters") { + // #CONNECTION# constructor default values and accessor docs + setRotationSensitivity(DomUtils::qrealFromDom(child, "rotSens", 1.0)); + setTranslationSensitivity( + DomUtils::qrealFromDom(child, "transSens", 1.0)); + setSpinningSensitivity(DomUtils::qrealFromDom(child, "spinSens", 0.3)); + setWheelSensitivity(DomUtils::qrealFromDom(child, "wheelSens", 1.0)); + setZoomSensitivity(DomUtils::qrealFromDom(child, "zoomSens", 1.0)); + } + child = child.nextSibling().toElement(); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// M o u s e h a n d l i n g // +//////////////////////////////////////////////////////////////////////////////// + +/*! Returns \c true when the ManipulatedFrame is being manipulated with the + mouse. + + Can be used to change the display of the manipulated object during + manipulation. + + When Camera::frame() of the CGAL::QGLViewer::camera() isManipulated(), + CGAL::QGLViewer::fastDraw() is used in place of CGAL::QGLViewer::draw() for scene + rendering. A simplified drawing will then allow for interactive camera + displacements. */ +CGAL_INLINE_FUNCTION +bool ManipulatedFrame::isManipulated() const { + return action_ != NO_MOUSE_ACTION; +} + +/*! Starts the spinning of the ManipulatedFrame. + +This method starts a timer that will call spin() every \p updateInterval +milliseconds. The ManipulatedFrame isSpinning() until you call stopSpinning(). +*/ +CGAL_INLINE_FUNCTION +void ManipulatedFrame::startSpinning(int updateInterval) { + isSpinning_ = true; + spinningTimer_.start(updateInterval); +} + +/*! Rotates the ManipulatedFrame by its spinningQuaternion(). Called by a timer + when the ManipulatedFrame isSpinning(). */ +CGAL_INLINE_FUNCTION +void ManipulatedFrame::spin() { rotate(spinningQuaternion()); } + +/* spin() and spinUpdate() differ since spin can be used by itself (for instance + by CGAL::QGLViewer::SCREEN_ROTATE) without a spun emission. Much nicer to use the + spinningQuaternion() and hence spin() for these incremental updates. Nothing + special to be done for continuous spinning with this design. */ +CGAL_INLINE_FUNCTION +void ManipulatedFrame::spinUpdate() { + spin(); + Q_EMIT spun(); +} + +#ifndef DOXYGEN +/*! Protected internal method used to handle mouse events. */ +CGAL_INLINE_FUNCTION +void ManipulatedFrame::startAction(int ma, bool withConstraint) { + action_ = (MouseAction)(ma); + + // #CONNECTION# manipulatedFrame::wheelEvent, + // manipulatedCameraFrame::wheelEvent and mouseReleaseEvent() restore previous + // constraint + if (withConstraint) + previousConstraint_ = NULL; + else { + previousConstraint_ = constraint(); + setConstraint(NULL); + } + + switch (action_) { + case ROTATE: + case SCREEN_ROTATE: + mouseSpeed_ = 0.0; + stopSpinning(); + break; + + case SCREEN_TRANSLATE: + dirIsFixed_ = false; + break; + + default: + break; + } +} + +/*! Updates mouse speed, measured in pixels/milliseconds. Should be called by +any method which wants to use mouse speed. Currently used to trigger spinning in +mouseReleaseEvent(). */ +CGAL_INLINE_FUNCTION +void ManipulatedFrame::computeMouseSpeed(const QMouseEvent *const e) { + const QPoint delta = (e->pos() - prevPos_); + const qreal dist = sqrt(qreal(delta.x() * delta.x() + delta.y() * delta.y())); + delay_ = last_move_time.restart(); + if (delay_ == 0) + // Less than a millisecond: assume delay = 1ms + mouseSpeed_ = dist; + else + mouseSpeed_ = dist / delay_; +} + +/*! Return 1 if mouse motion was started horizontally and -1 if it was more +vertical. Returns 0 if this could not be determined yet (perfect diagonal +motion, rare). */ +CGAL_INLINE_FUNCTION +int ManipulatedFrame::mouseOriginalDirection(const QMouseEvent *const e) { + static bool horiz = + true; // Two simultaneous manipulatedFrame require two mice ! + + if (!dirIsFixed_) { + const QPoint delta = e->pos() - pressPos_; + dirIsFixed_ = abs(delta.x()) != abs(delta.y()); + horiz = abs(delta.x()) > abs(delta.y()); + } + + if (dirIsFixed_) + if (horiz) + return 1; + else + return -1; + else + return 0; +} + +CGAL_INLINE_FUNCTION +qreal ManipulatedFrame::deltaWithPrevPos(QMouseEvent *const event, + Camera *const camera) const { + qreal dx = qreal(event->x() - prevPos_.x()) / camera->screenWidth(); + qreal dy = qreal(event->y() - prevPos_.y()) / camera->screenHeight(); + + qreal value = fabs(dx) > fabs(dy) ? dx : dy; + return value * zoomSensitivity(); +} + +CGAL_INLINE_FUNCTION +qreal ManipulatedFrame::wheelDelta(const QWheelEvent *event) const { + static const qreal WHEEL_SENSITIVITY_COEF = 8E-4; + return event->delta() * wheelSensitivity() * WHEEL_SENSITIVITY_COEF; +} + +CGAL_INLINE_FUNCTION +void ManipulatedFrame::zoom(qreal delta, const Camera *const camera) { + Vec trans(0.0, 0.0, (camera->position() - position()).norm() * delta); + + trans = camera->frame()->orientation().rotate(trans); + if (referenceFrame()) + trans = referenceFrame()->transformOf(trans); + translate(trans); +} + +#endif // DOXYGEN + +/*! Initiates the ManipulatedFrame mouse manipulation. + +Overloading of MouseGrabber::mousePressEvent(). See also mouseMoveEvent() and +mouseReleaseEvent(). + +The mouse behavior depends on which button is pressed. See the CGAL::QGLViewer mouse page for details. */ +CGAL_INLINE_FUNCTION +void ManipulatedFrame::mousePressEvent(QMouseEvent *const event, + Camera *const camera) { + Q_UNUSED(camera); + + if (grabsMouse()) + keepsGrabbingMouse_ = true; + + // #CONNECTION setMouseBinding + // action_ should no longer possibly be NO_MOUSE_ACTION since this value is + // not inserted in mouseBinding_ + // if (action_ == NO_MOUSE_ACTION) + // event->ignore(); + + prevPos_ = pressPos_ = event->pos(); +} + +/*! Modifies the ManipulatedFrame according to the mouse motion. + +Actual behavior depends on mouse bindings. See the MouseAction enum +and the CGAL::QGLViewer mouse page for details. + +The \p camera is used to fit the mouse motion with the display parameters (see +Camera::screenWidth(), Camera::screenHeight(), Camera::fieldOfView()). + +Emits the manipulated() signal. */ +CGAL_INLINE_FUNCTION +void ManipulatedFrame::mouseMoveEvent(QMouseEvent *const event, + Camera *const camera) { + switch (action_) { + case TRANSLATE: { + const QPoint delta = event->pos() - prevPos_; + Vec trans(delta.x(), -delta.y(), 0.0); + // Scale to fit the screen mouse displacement + switch (camera->type()) { + case Camera::PERSPECTIVE: + trans *= 2.0 * tan(camera->fieldOfView() / 2.0) * + fabs((camera->frame()->coordinatesOf(position())).z) / + camera->screenHeight(); + break; + case Camera::ORTHOGRAPHIC: { + GLdouble w, h; + camera->getOrthoWidthHeight(w, h); + trans[0] *= 2.0 * w / camera->screenWidth(); + trans[1] *= 2.0 * h / camera->screenHeight(); + break; + } + } + // Transform to world coordinate system. + trans = + camera->frame()->orientation().rotate(translationSensitivity() * trans); + // And then down to frame + if (referenceFrame()) + trans = referenceFrame()->transformOf(trans); + translate(trans); + break; + } + + case ZOOM: { + zoom(deltaWithPrevPos(event, camera), camera); + break; + } + + case SCREEN_ROTATE: { + Vec trans = camera->projectedCoordinatesOf(position()); + + const qreal prev_angle = + atan2(prevPos_.y() - trans[1], prevPos_.x() - trans[0]); + const qreal angle = atan2(event->y() - trans[1], event->x() - trans[0]); + + const Vec axis = + transformOf(camera->frame()->inverseTransformOf(Vec(0.0, 0.0, -1.0))); + Quaternion rot(axis, angle - prev_angle); + //#CONNECTION# These two methods should go together (spinning detection and + // activation) + computeMouseSpeed(event); + setSpinningQuaternion(rot); + spin(); + break; + } + + case SCREEN_TRANSLATE: { + Vec trans; + int dir = mouseOriginalDirection(event); + if (dir == 1) + trans.setValue(event->x() - prevPos_.x(), 0.0, 0.0); + else if (dir == -1) + trans.setValue(0.0, prevPos_.y() - event->y(), 0.0); + + switch (camera->type()) { + case Camera::PERSPECTIVE: + trans *= 2.0 * tan(camera->fieldOfView() / 2.0) * + fabs((camera->frame()->coordinatesOf(position())).z) / + camera->screenHeight(); + break; + case Camera::ORTHOGRAPHIC: { + GLdouble w, h; + camera->getOrthoWidthHeight(w, h); + trans[0] *= 2.0 * w / camera->screenWidth(); + trans[1] *= 2.0 * h / camera->screenHeight(); + break; + } + } + // Transform to world coordinate system. + trans = + camera->frame()->orientation().rotate(translationSensitivity() * trans); + // And then down to frame + if (referenceFrame()) + trans = referenceFrame()->transformOf(trans); + + translate(trans); + break; + } + + case ROTATE: { + Vec trans = camera->projectedCoordinatesOf(position()); + Quaternion rot = deformedBallQuaternion(event->x(), event->y(), trans[0], + trans[1], camera); + trans = Vec(-rot[0], -rot[1], -rot[2]); + trans = camera->frame()->orientation().rotate(trans); + trans = transformOf(trans); + rot[0] = trans[0]; + rot[1] = trans[1]; + rot[2] = trans[2]; + //#CONNECTION# These two methods should go together (spinning detection and + // activation) + computeMouseSpeed(event); + setSpinningQuaternion(rot); + spin(); + break; + } + + case MOVE_FORWARD: + case MOVE_BACKWARD: + case LOOK_AROUND: + case ROLL: + case DRIVE: + case ZOOM_ON_REGION: + // These MouseAction values make no sense for a manipulatedFrame + break; + + case NO_MOUSE_ACTION: + // Possible when the ManipulatedFrame is a MouseGrabber. This method is then + // called without startAction because of mouseTracking. + break; + } + + if (action_ != NO_MOUSE_ACTION) { + prevPos_ = event->pos(); + Q_EMIT manipulated(); + } +} + +/*! Stops the ManipulatedFrame mouse manipulation. + +Overloading of MouseGrabber::mouseReleaseEvent(). + +If the action was a ROTATE MouseAction, a continuous +spinning is possible if the speed of the mouse cursor is larger than +spinningSensitivity() when the button is released. Press the rotate button again +to stop spinning. See startSpinning() and isSpinning(). */ +CGAL_INLINE_FUNCTION +void ManipulatedFrame::mouseReleaseEvent(QMouseEvent *const event, + Camera *const camera) { + Q_UNUSED(event); + Q_UNUSED(camera); + + keepsGrabbingMouse_ = false; + + if (previousConstraint_) + setConstraint(previousConstraint_); + + if (((action_ == ROTATE) || + (action_ == SCREEN_ROTATE)) && + (mouseSpeed_ >= spinningSensitivity())) + startSpinning(delay_); + + action_ = NO_MOUSE_ACTION; +} + +/*! Overloading of MouseGrabber::mouseDoubleClickEvent(). + +Left button double click aligns the ManipulatedFrame with the \p camera axis +(see alignWithFrame() and ALIGN_FRAME). Right button projects the +ManipulatedFrame on the \p camera view direction. */ +CGAL_INLINE_FUNCTION +void ManipulatedFrame::mouseDoubleClickEvent(QMouseEvent *const event, + Camera *const camera) { + if (event->modifiers() == ::Qt::NoModifier) + switch (event->button()) { + case ::Qt::LeftButton: + alignWithFrame(camera->frame()); + break; + case ::Qt::RightButton: + projectOnLine(camera->position(), camera->viewDirection()); + break; + default: + break; + } +} + +/*! Overloading of MouseGrabber::wheelEvent(). + +Using the wheel is equivalent to a ZOOM MouseAction. See + CGAL::QGLViewer::setWheelBinding(), setWheelSensitivity(). */ +CGAL_INLINE_FUNCTION +void ManipulatedFrame::wheelEvent(QWheelEvent *const event, + Camera *const camera) { + //#CONNECTION# CGAL::QGLViewer::setWheelBinding + if (action_ == ZOOM) { + zoom(wheelDelta(event), camera); + Q_EMIT manipulated(); + } + + // #CONNECTION# startAction should always be called before + if (previousConstraint_) + setConstraint(previousConstraint_); + + action_ = NO_MOUSE_ACTION; +} + +//////////////////////////////////////////////////////////////////////////////// + +/*! Returns "pseudo-distance" from (x,y) to ball of radius size. +\arg for a point inside the ball, it is proportional to the euclidean distance +to the ball \arg for a point outside the ball, it is proportional to the inverse +of this distance (tends to zero) on the ball, the function is continuous. */ +static qreal projectOnBall(qreal x, qreal y) { + // If you change the size value, change angle computation in + // deformedBallQuaternion(). + const qreal size = 1.0; + const qreal size2 = size * size; + const qreal size_limit = size2 * 0.5; + + const qreal d = x * x + y * y; + return d < size_limit ? sqrt(size2 - d) : size_limit / sqrt(d); +} + +#ifndef DOXYGEN +/*! Returns a quaternion computed according to the mouse motion. Mouse positions +are projected on a deformed ball, centered on (\p cx,\p cy). */ +Quaternion +CGAL_INLINE_FUNCTION +ManipulatedFrame::deformedBallQuaternion(int x, int y, qreal cx, qreal cy, + const Camera *const camera) { + // Points on the deformed ball + qreal px = + rotationSensitivity() * (prevPos_.x() - cx) / camera->screenWidth(); + qreal py = + rotationSensitivity() * (cy - prevPos_.y()) / camera->screenHeight(); + qreal dx = rotationSensitivity() * (x - cx) / camera->screenWidth(); + qreal dy = rotationSensitivity() * (cy - y) / camera->screenHeight(); + + const Vec p1(px, py, projectOnBall(px, py)); + const Vec p2(dx, dy, projectOnBall(dx, dy)); + // Approximation of rotation angle + // Should be divided by the projectOnBall size, but it is 1.0 + const Vec axis = cross(p2, p1); + const qreal angle = + 5.0 * + asin(sqrt(axis.squaredNorm() / p1.squaredNorm() / p2.squaredNorm())); + return Quaternion(axis, angle); +} +#endif // DOXYGEN +}} diff --git a/GraphicsView/include/CGAL/Qt/mouseGrabber.h b/GraphicsView/include/CGAL/Qt/mouseGrabber.h new file mode 100644 index 00000000000..02d78f52750 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/mouseGrabber.h @@ -0,0 +1,294 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 + +#ifndef QGLVIEWER_MOUSE_GRABBER_H +#define QGLVIEWER_MOUSE_GRABBER_H + +#include + +#include + + +namespace CGAL{ +class QGLViewer; +namespace qglviewer { +class Camera; + +/*! \brief Abstract class for objects that grab mouse focus in a CGAL::QGLViewer. + \class MouseGrabber mouseGrabber.h CGAL::QGLViewer/mouseGrabber.h + + MouseGrabber are objects which react to the mouse cursor, usually when it + hovers over them. This abstract class only provides an interface for all these + objects: their actual behavior has to be defined in a derived class. + +

How does it work ?

+ + All the created MouseGrabber are grouped in a MouseGrabberPool(). The + CGAL::QGLViewers parse this pool, calling all the MouseGrabbers' checkIfGrabsMouse() + methods that setGrabsMouse() if desired. + + When a MouseGrabber grabsMouse(), it becomes the CGAL::QGLViewer::mouseGrabber(). + All the mouse events (mousePressEvent(), mouseReleaseEvent(), + mouseMoveEvent(), mouseDoubleClickEvent() and wheelEvent()) are then + transmitted to the CGAL::QGLViewer::mouseGrabber() instead of being normally + processed. This continues while grabsMouse() (updated using + checkIfGrabsMouse()) returns \c true. + + If you want to (temporarily) disable a specific MouseGrabbers, you can remove + it from this pool using removeFromMouseGrabberPool(). You can also disable a + MouseGrabber in a specific CGAL::QGLViewer using + CGAL::QGLViewer::setMouseGrabberIsEnabled(). + +

Implementation details

+ + In order to make MouseGrabber react to mouse events, mouse tracking has to be + activated in the CGAL::QGLViewer which wants to use MouseGrabbers: \code init() { + setMouseTracking(true); } \endcode Call \c QOpenGLWidget::hasMouseTracking() + to get the current state of this flag. + + The \p camera parameter of the different mouse event methods is a pointer to + the CGAL::QGLViewer::camera() of the CGAL::QGLViewer that uses the MouseGrabber. It can be + used to compute 2D to 3D coordinates conversion using + Camera::projectedCoordinatesOf() and Camera::unprojectedCoordinatesOf(). + + Very complex behaviors can be implemented using this framework: auto-selected + objects (no need to press a key to use them), automatic drop-down menus, 3D + GUI, spinners using the wheelEvent(), and whatever your imagination creates. + See the mouseGrabber example for + an illustration. + + Note that ManipulatedFrame are MouseGrabber: see the keyFrame example for an illustration. + Every created ManipulatedFrame is hence present in the MouseGrabberPool() + (note however that ManipulatedCameraFrame are not inserted). + +

Example

+ + Here is for instance a draft version of a MovableObject class. Instances of + these class can freely be moved on screen using the mouse, as movable + post-it-like notes: \code class MovableObject : public MouseGrabber + { + public: + MovableObject() : pos(0,0), moved(false) {} + + void checkIfGrabsMouse(int x, int y, const CGAL::qglviewer::Camera* const) + { + // MovableObject is active in a region of 5 pixels around its pos. + // May depend on the actual shape of the object. Customize as desired. + // Once clicked (moved = true), it keeps grabbing mouse until button is + released. setGrabsMouse( moved || ((pos-QPoint(x,y)).manhattanLength() < 5) ); + } + + void mousePressEvent( QMouseEvent* const e, Camera* const) { prevPos = + e->pos(); moved = true; } + + void mouseMoveEvent(QMouseEvent* const e, const Camera* const) + { + if (moved) + { + // Add position delta to current pos + pos += e->pos() - prevPos; + prevPos = e->pos(); + } + } + + void mouseReleaseEvent(QMouseEvent* const, Camera* const) { moved = false; } + + void draw() + { + // The object is drawn centered on its pos, with different possible aspects: + if (grabsMouse()) + if (moved) + // Object being moved, maybe a transparent display + else + // Object ready to be moved, maybe a highlighted visual feedback + else + // Normal display + } + + private: + QPoint pos, prevPos; + bool moved; + }; + \endcode + Note that the different event callback methods are called only once the + MouseGrabber grabsMouse(). \nosubgrouping */ +class CGAL_QT_EXPORT MouseGrabber { +#ifndef DOXYGEN + friend class ::CGAL::QGLViewer; +#endif + +public: + MouseGrabber(); + /*! Virtual destructor. Removes the MouseGrabber from the MouseGrabberPool(). + */ + virtual ~MouseGrabber() { MouseGrabber::MouseGrabberPool().removeAll(this); } + + /*! @name Mouse grabbing detection */ + //@{ +public: + /*! Pure virtual method, called by the CGAL::QGLViewers before they test if the + MouseGrabber grabsMouse(). Should setGrabsMouse() according to the mouse + position. + + This is the core method of the MouseGrabber. It has to be overloaded in your + derived class. Its goal is to update the grabsMouse() flag according to the + mouse and MouseGrabber current positions, using setGrabsMouse(). + + grabsMouse() is usually set to \c true when the mouse cursor is close enough + to the MouseGrabber position. It should also be set to \c false when the mouse + cursor leaves this region in order to release the mouse focus. + + \p x and \p y are the mouse cursor coordinates (Qt coordinate system: (0,0) + corresponds to the upper left corner). + + A typical implementation will look like: + \code + // (posX,posY) is the position of the MouseGrabber on screen. + // Here, distance to mouse must be less than 10 pixels to activate the + MouseGrabber. setGrabsMouse( sqrt((x-posX)*(x-posX) + (y-posY)*(y-posY)) < + 10); \endcode + + If the MouseGrabber position is defined in 3D, use the \p camera parameter, + corresponding to the calling CGAL::QGLViewer Camera. Project on screen and then + compare the projected coordinates: \code Vec proj = + camera->projectedCoordinatesOf(myMouseGrabber->frame()->position()); + setGrabsMouse((fabs(x-proj.x) < 5) && (fabs(y-proj.y) < 2)); // Rectangular + region \endcode + + See examples in the detailed description section and + in the mouseGrabber example. */ + virtual void checkIfGrabsMouse(int x, int y, const Camera *const camera) = 0; + + /*! Returns \c true when the MouseGrabber grabs the CGAL::QGLViewer's mouse events. + + This flag is set with setGrabsMouse() by the checkIfGrabsMouse() method. */ + bool grabsMouse() const { return grabsMouse_; } + +protected: + /*! Sets the grabsMouse() flag. Normally used by checkIfGrabsMouse(). */ + void setGrabsMouse(bool grabs) { grabsMouse_ = grabs; } + //@} + + /*! @name MouseGrabber pool */ + //@{ +public: + /*! Returns a list containing pointers to all the active MouseGrabbers. + + Used by the CGAL::QGLViewer to parse all the MouseGrabbers and to check if any of + them grabsMouse() using checkIfGrabsMouse(). + + You should not have to directly use this list. Use + removeFromMouseGrabberPool() and addInMouseGrabberPool() to modify this list. +*/ + static QList &MouseGrabberPool(); + + /*! Returns \c true if the MouseGrabber is currently in the MouseGrabberPool() + list. + + Default value is \c true. When set to \c false using + removeFromMouseGrabberPool(), the CGAL::QGLViewers no longer checkIfGrabsMouse() on + this MouseGrabber. Use addInMouseGrabberPool() to insert it back. */ + bool isInMouseGrabberPool() const { + return MouseGrabber::MouseGrabberPool().contains( + const_cast(this)); + } + void addInMouseGrabberPool(); + void removeFromMouseGrabberPool(); + void clearMouseGrabberPool(bool autoDelete = false); + //@} + + /*! @name Mouse event handlers */ + //@{ +protected: + /*! Callback method called when the MouseGrabber grabsMouse() and a mouse + button is pressed. + + + The MouseGrabber will typically start an action or change its state when a + mouse button is pressed. mouseMoveEvent() (called at each mouse displacement) + will then update the MouseGrabber accordingly and mouseReleaseEvent() (called + when the mouse button is released) will terminate this action. + + Use the \p event QMouseEvent::state() and QMouseEvent::button() to test the + keyboard and button state and possibly change the MouseGrabber behavior + accordingly. + + See the detailed description section and the mouseGrabber example for examples. + + See the \c QOpenGLWidget::mousePressEvent() and the \c QMouseEvent + documentations for details. */ + virtual void mousePressEvent(QMouseEvent *const event, Camera *const camera) { + Q_UNUSED(event); + Q_UNUSED(camera); + } + /*! Callback method called when the MouseGrabber grabsMouse() and a mouse + button is double clicked. + + See the \c QOpenGLWidget::mouseDoubleClickEvent() and the \c QMouseEvent + documentations for details. */ + virtual void mouseDoubleClickEvent(QMouseEvent *const event, + Camera *const camera) { + Q_UNUSED(event); + Q_UNUSED(camera); + } + /*! Mouse release event callback method. See mousePressEvent(). */ + virtual void mouseReleaseEvent(QMouseEvent *const event, + Camera *const camera) { + Q_UNUSED(event); + Q_UNUSED(camera); + } + /*! Callback method called when the MouseGrabber grabsMouse() and the mouse is + moved while a button is pressed. + + This method will typically update the state of the MouseGrabber from the mouse + displacement. See the mousePressEvent() documentation for details. */ + virtual void mouseMoveEvent(QMouseEvent *const event, Camera *const camera) { + Q_UNUSED(event); + Q_UNUSED(camera); + } + /*! Callback method called when the MouseGrabber grabsMouse() and the mouse + wheel is used. + + See the \c QOpenGLWidget::wheelEvent() and the \c QWheelEvent documentations + for details. */ + virtual void wheelEvent(QWheelEvent *const event, Camera *const camera) { + Q_UNUSED(event); + Q_UNUSED(camera); + } + //@} + +private: + // Copy constructor and opertor= are declared private and undefined + // Prevents everyone from trying to use them + MouseGrabber(const MouseGrabber &); + MouseGrabber &operator=(const MouseGrabber &); + + bool grabsMouse_; + +}; + +}} // namespace CGAL::qglviewer + +#ifdef CGAL_HEADER_ONLY +//#include +#endif // CGAL_HEADER_ONLY +#endif // QGLVIEWER_MOUSE_GRABBER_H diff --git a/GraphicsView/include/CGAL/Qt/mouseGrabber_impl.h b/GraphicsView/include/CGAL/Qt/mouseGrabber_impl.h new file mode 100644 index 00000000000..1550214ddb8 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/mouseGrabber_impl.h @@ -0,0 +1,96 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 + +#ifdef CGAL_HEADER_ONLY +#define CGAL_INLINE_FUNCTION inline + +#include + +#else +#define CGAL_INLINE_FUNCTION +#endif + +#include + +namespace CGAL{ +namespace qglviewer{ + + +// Static private variable +CGAL_INLINE_FUNCTION + QList &MouseGrabber::MouseGrabberPool() { + static QList MouseGrabberPool_; + void* p = qApp->property("qglviewer mouse grabber pool").value(); + if(p == 0) { + p = (void*)(&MouseGrabberPool_); + qApp->setProperty("qglviewer mouse grabber pool", QVariant::fromValue(p)); + } + return *static_cast * >(p); +} + +/*! Default constructor. + +Adds the created MouseGrabber in the MouseGrabberPool(). grabsMouse() is set to +\c false. */ +CGAL_INLINE_FUNCTION +MouseGrabber::MouseGrabber() : grabsMouse_(false) { addInMouseGrabberPool(); } + +/*! Adds the MouseGrabber in the MouseGrabberPool(). + +All created MouseGrabber are automatically added in the MouseGrabberPool() by +the constructor. Trying to add a MouseGrabber that already +isInMouseGrabberPool() has no effect. + +Use removeFromMouseGrabberPool() to remove the MouseGrabber from the list, so +that it is no longer tested with checkIfGrabsMouse() by the CGAL::QGLViewer, and hence +can no longer grab mouse focus. Use isInMouseGrabberPool() to know the current +state of the MouseGrabber. */ +CGAL_INLINE_FUNCTION +void MouseGrabber::addInMouseGrabberPool() { + if (!isInMouseGrabberPool()) + MouseGrabber::MouseGrabberPool().append(this); +} + +/*! Removes the MouseGrabber from the MouseGrabberPool(). + +See addInMouseGrabberPool() for details. Removing a MouseGrabber that is not in +MouseGrabberPool() has no effect. */ +CGAL_INLINE_FUNCTION +void MouseGrabber::removeFromMouseGrabberPool() { + if (isInMouseGrabberPool()) + MouseGrabber::MouseGrabberPool().removeAll(const_cast(this)); +} + +/*! Clears the MouseGrabberPool(). + + Use this method only if it is faster to clear the MouseGrabberPool() and then + to add back a few MouseGrabbers than to remove each one independently. Use + CGAL::QGLViewer::setMouseTracking(false) instead if you want to disable mouse + grabbing. + + When \p autoDelete is \c true, the MouseGrabbers of the MouseGrabberPool() are + actually deleted (use this only if you're sure of what you do). */ +CGAL_INLINE_FUNCTION +void MouseGrabber::clearMouseGrabberPool(bool autoDelete) { + if (autoDelete) + qDeleteAll(MouseGrabber::MouseGrabberPool()); + MouseGrabber::MouseGrabberPool().clear(); +} +}} diff --git a/GraphicsView/include/CGAL/Qt/qglviewer.h b/GraphicsView/include/CGAL/Qt/qglviewer.h new file mode 100644 index 00000000000..77cc5a354f3 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/qglviewer.h @@ -0,0 +1,1246 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 + +#ifndef QGLVIEWER_QGLVIEWER_H +#define QGLVIEWER_QGLVIEWER_H +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +class QTabWidget; +class QImage; + +namespace CGAL{ +/*! \brief A versatile 3D OpenGL viewer based on QOpenGLWidget. +\class QGLViewer qglviewer.h QGLViewer/qglviewer.h + +It features many classical viewer functionalities, such as a camera trackball, +manipulated objects and much more. Its main goal is to ease the development of +new 3D applications. + +New users should read the introduction page +to get familiar with important notions such as sceneRadius(), sceneCenter() and +the world coordinate system. Try the numerous simple examples to discover the possibilities and +understand how it works. + +

Usage

+ +To use a QGLViewer, derive you viewer class from the QGLViewer and overload its +draw() virtual method. See the simpleViewer example for an +illustration. + +An other option is to connect your drawing methods to the signals emitted by the +QGLViewer (Qt's callback mechanism). See the callback example for a complete +implementation. + +\nosubgrouping */ +class CGAL_QT_EXPORT QGLViewer : public QOpenGLWidget, public QOpenGLFunctions_2_1 { + Q_OBJECT + +public: + explicit QGLViewer(QGLContext* context, QWidget *parent = 0, + ::Qt::WindowFlags flags = 0); + explicit QGLViewer(QWidget *parent = 0, + ::Qt::WindowFlags flags = 0); + + virtual ~QGLViewer(); + + /*! @name Display of visual hints */ + //@{ +public: + /*! Returns \c true if the world axis is drawn by the viewer. + + Set by setAxisIsDrawn() or toggleAxisIsDrawn(). Default value is \c false. */ + bool axisIsDrawn() const { return axisIsDrawn_; } + /*! Returns \c true if a XY grid is drawn by the viewer. + + Set by setGridIsDrawn() or toggleGridIsDrawn(). Default value is \c false. */ + bool gridIsDrawn() const { return gridIsDrawn_; } + /*! Returns \c true if the viewer displays the current frame rate (Frames Per + Second). + + Use QApplication::setFont() to define the display font (see drawText()). + + Set by setFPSIsDisplayed() or toggleFPSIsDisplayed(). Use currentFPS() to get + the current FPS. Default value is \c false. */ + bool FPSIsDisplayed() const { return FPSIsDisplayed_; } + /*! Returns \c true if text display (see drawText()) is enabled. + + Set by setTextIsEnabled() or toggleTextIsEnabled(). This feature conveniently + removes all the possibly displayed text, cleaning display. Default value is \c + true. */ + bool textIsEnabled() const { return textIsEnabled_; } + + /*! Returns \c true if the camera() is being edited in the viewer. + + Set by setCameraIsEdited() or toggleCameraIsEdited(). Default value is \p + false. + + The current implementation is limited: the defined camera() paths (see + qglviewer::Camera::keyFrameInterpolator()) are simply displayed using + qglviewer::Camera::drawAllPaths(). Actual camera and path edition will be + implemented in the future. */ + bool cameraIsEdited() const { return cameraIsEdited_; } + +public Q_SLOTS: + /*! Sets the state of axisIsDrawn(). Emits the axisIsDrawnChanged() signal. + * See also toggleAxisIsDrawn(). */ + void setAxisIsDrawn(bool draw = true) { + if(!draw) + axis_size = 0; + axisIsDrawn_ = draw; + Q_EMIT axisIsDrawnChanged(draw); + update(); + } + /*! Sets the state of gridIsDrawn(). Emits the gridIsDrawnChanged() signal. + * See also toggleGridIsDrawn(). */ + void setGridIsDrawn(bool draw = true) { + if(!draw) + { + grid_size=0; + g_axis_size=0; + } + gridIsDrawn_ = draw; + Q_EMIT gridIsDrawnChanged(draw); + update(); + } + /*! Sets the state of FPSIsDisplayed(). Emits the FPSIsDisplayedChanged() + * signal. See also toggleFPSIsDisplayed(). */ + void setFPSIsDisplayed(bool display = true) { + FPSIsDisplayed_ = display; + Q_EMIT FPSIsDisplayedChanged(display); + update(); + } + /*! Sets the state of textIsEnabled(). Emits the textIsEnabledChanged() + * signal. See also toggleTextIsEnabled(). */ + void setTextIsEnabled(bool enable = true) { + textIsEnabled_ = enable; + Q_EMIT textIsEnabledChanged(enable); + update(); + } + void setCameraIsEdited(bool edit = true); + + /*! Toggles the state of axisIsDrawn(). See also setAxisIsDrawn(). */ + void toggleAxisIsDrawn() { setAxisIsDrawn(!axisIsDrawn()); } + /*! Toggles the state of gridIsDrawn(). See also setGridIsDrawn(). */ + void toggleGridIsDrawn() { setGridIsDrawn(!gridIsDrawn()); } + /*! Toggles the state of FPSIsDisplayed(). See also setFPSIsDisplayed(). */ + void toggleFPSIsDisplayed() { setFPSIsDisplayed(!FPSIsDisplayed()); } + /*! Toggles the state of textIsEnabled(). See also setTextIsEnabled(). */ + void toggleTextIsEnabled() { setTextIsEnabled(!textIsEnabled()); } + /*! Toggles the state of cameraIsEdited(). See also setCameraIsEdited(). */ + void toggleCameraIsEdited() { setCameraIsEdited(!cameraIsEdited()); } + //@} + + /*! @name Viewer's colors */ + //@{ +public: + /*! Returns the background color of the viewer. + + This method is provided for convenience since the background color is an + OpenGL state variable set with \c glClearColor(). However, this internal + representation has the advantage that it is saved (resp. restored) with + saveStateToFile() (resp. restoreStateFromFile()). + + Use setBackgroundColor() to define and activate a background color. + + \attention Each QColor component is an integer ranging from 0 to 255. This + differs from the qreal values used by \c glClearColor() which are in the + 0.0-1.0 range. Default value is (51, 51, 51) (dark gray). You may have to + change foregroundColor() accordingly. + + \attention This method does not return the current OpenGL clear color as \c + glGet() does. Instead, it returns the QGLViewer internal variable. If you + directly use \c glClearColor() or \c qglClearColor() instead of + setBackgroundColor(), the two results will differ. */ + QColor backgroundColor() const { return backgroundColor_; } + + /*! Returns the foreground color used by the viewer. + + This color is used when FPSIsDisplayed(), gridIsDrawn(), to display the camera + paths when the cameraIsEdited(). + + \attention Each QColor component is an integer in the range 0-255. This + differs from the qreal values used by \c glColor3f() which are in the range + 0-1. Default value is (180, 180, 180) (light gray). + + Use \c qglColor(foregroundColor()) to set the current OpenGL color to the + foregroundColor(). + + See also backgroundColor(). */ + QColor foregroundColor() const { return foregroundColor_; } +public Q_SLOTS: + /*! Sets the backgroundColor() of the viewer and calls \c qglClearColor(). See + also setForegroundColor(). */ + void setBackgroundColor(const QColor &color) { + backgroundColor_ = color; + glClearColor(GLclampf(color.redF()), + GLclampf(color.greenF()), + GLclampf(color.blueF()), + GLclampf(color.alphaF())); + } + /*! Sets the foregroundColor() of the viewer, used to draw visual hints. See + * also setBackgroundColor(). */ + void setForegroundColor(const QColor &color) { foregroundColor_ = color; } + //@} + + /*! @name Scene dimensions */ + //@{ +public: + /*! Returns the scene radius. + + The entire displayed scene should be included in a sphere of radius + sceneRadius(), centered on sceneCenter(). + + This approximate value is used by the camera() to set + qglviewer::Camera::zNear() and qglviewer::Camera::zFar(). It is also used to + showEntireScene() or to scale the world axis display.. + + Default value is 1.0. This method is equivalent to camera()->sceneRadius(). + See setSceneRadius(). */ + qreal sceneRadius() const; + /*! Returns the scene center, defined in world coordinates. + + See sceneRadius() for details. + + Default value is (0,0,0). Simply a wrapper for camera()->sceneCenter(). Set + using setSceneCenter(). + + Do not mismatch this value (that only depends on the scene) with the + qglviewer::Camera::pivotPoint(). */ + qglviewer::Vec sceneCenter() const; + +public Q_SLOTS: + /*! Sets the sceneRadius(). + + The camera() qglviewer::Camera::flySpeed() is set to 1% of this value by + this method. Simple wrapper around camera()->setSceneRadius(). */ + virtual void setSceneRadius(qreal radius); + + /*! Sets the sceneCenter(), defined in world coordinates. + + \attention The qglviewer::Camera::pivotPoint() is set to the sceneCenter() + value by this method. */ + virtual void setSceneCenter(const qglviewer::Vec ¢er); + + /*! Convenient way to call setSceneCenter() and setSceneRadius() from a (world + axis aligned) bounding box of the scene. Takes the offset into account. + + This is equivalent to: + \code + setSceneCenter((min+max) / 2.0); + setSceneRadius((max-min).norm() / 2.0); + \endcode */ + void setSceneBoundingBox(const qglviewer::Vec &min, + const qglviewer::Vec &max); + + /*! Moves the camera so that the entire scene is visible. + + Simple wrapper around qglviewer::Camera::showEntireScene(). */ + void showEntireScene() ; + //@} + + /*! @name Associated objects */ + //@{ +public: + /*! Returns the associated qglviewer::Camera, never \c NULL. */ + qglviewer::Camera *camera() const { return camera_; } + + /*! Returns the viewer's qglviewer::ManipulatedFrame. + + This qglviewer::ManipulatedFrame can be moved with the mouse when the + associated mouse bindings are used (default is when pressing the \c Control + key with any mouse button). Use setMouseBinding() to define new bindings. + + See the manipulatedFrame + example for a complete implementation. + + Default value is \c NULL, meaning that no qglviewer::ManipulatedFrame is set. +*/ + qglviewer::ManipulatedFrame *manipulatedFrame() const { + return manipulatedFrame_; + } + +public Q_SLOTS: + void setCamera(qglviewer::Camera *const camera); + void setManipulatedFrame(qglviewer::ManipulatedFrame *frame); + //@} + + /*! @name Mouse grabbers */ + //@{ +public: + /*! Returns the current qglviewer::MouseGrabber, or \c NULL if no + qglviewer::MouseGrabber currently grabs mouse events. + + When qglviewer::MouseGrabber::grabsMouse(), the different mouse events are + sent to the mouseGrabber() instead of their usual targets (camera() or + manipulatedFrame()). + + See the qglviewer::MouseGrabber documentation for details on MouseGrabber's + mode of operation. + + In order to use MouseGrabbers, you need to enable mouse tracking (so that + mouseMoveEvent() is called even when no mouse button is pressed). Add this + line in init() or in your viewer constructor: \code setMouseTracking(true); + \endcode + Note that mouse tracking is disabled by default. Use + QWidget::hasMouseTracking() to retrieve current state. */ + qglviewer::MouseGrabber *mouseGrabber() const { return mouseGrabber_; } + + void + setMouseGrabberIsEnabled(const qglviewer::MouseGrabber *const mouseGrabber, + bool enabled = true); + /*! Returns \c true if \p mouseGrabber is enabled. + + Default value is \c true for all MouseGrabbers. When set to \c false using + setMouseGrabberIsEnabled(), the specified \p mouseGrabber will never become + the mouseGrabber() of this QGLViewer. This is useful when you use several + viewers: some MouseGrabbers may only have a meaning for some specific viewers + and should not be selectable in others. + + You can also use qglviewer::MouseGrabber::removeFromMouseGrabberPool() to + completely disable a MouseGrabber in all the QGLViewers. */ + bool + mouseGrabberIsEnabled(const qglviewer::MouseGrabber *const mouseGrabber) { + return !disabledMouseGrabbers_.contains( + reinterpret_cast(mouseGrabber)); + } +public Q_SLOTS: + void setMouseGrabber(qglviewer::MouseGrabber *mouseGrabber); + //@} + + /*! @name State of the viewer */ + //@{ +public: + /*! Returns the aspect ratio of the viewer's widget (width() / height()). */ + qreal aspectRatio() const { return width() / static_cast(height()); } + /*! Returns the current averaged viewer frame rate. + + This value is computed and averaged over 20 successive frames. It only changes + every 20 draw() (previously computed value is otherwise returned). + + This method is useful for true real-time applications that may adapt their + computational load accordingly in order to maintain a given frequency. + + This value is meaningful only when draw() is regularly called, either using a + \c QTimer, when animationIsStarted() or when the camera is manipulated with + the mouse. */ + qreal currentFPS() { return f_p_s_; } + /*! + * Returns the string used to display the current fps. + */ + QString fpsString() { return fpsString_; } + /*! Returns \c true if the viewer is in fullScreen mode. + + Default value is \c false. Set by setFullScreen() or toggleFullScreen(). + + Note that if the QGLViewer is embedded in an other QWidget, it returns \c true + when the top level widget is in full screen mode. */ + bool isFullScreen() const { return fullScreen_; } + /*! Returns \c true if the viewer displays in stereo. + + The QGLViewer object must be created with a stereo format to handle + stereovision: \code QGLFormat format; format.setStereoDisplay( TRUE ); + QGLViewer viewer(format); + \endcode + The hardware needs to support stereo display. Try the stereoViewer example to check. + + Set by setStereoDisplay() or toggleStereoDisplay(). Default value is \c false. + + Stereo is performed using the Parallel axis asymmetric frustum perspective + projection method. See Camera::loadProjectionMatrixStereo() and + Camera::loadModelViewMatrixStereo(). + + The stereo parameters are defined by the camera(). See + qglviewer::Camera::setIODistance(), + qglviewer::Camera::setPhysicalScreenWidth() and + qglviewer::Camera::setFocusDistance(). */ + bool displaysInStereo() const { return stereo_; } + /*! Returns the recommended size for the QGLViewer. Default value is 600x400 + * pixels. */ + virtual QSize sizeHint() const { return QSize(600, 400); } + /*! + * Sets the offset of the scene. The offset is the difference between the origin + * of the world and the origin of the scene. It is relevant when the whole scene is translated + * of a big number, because there is a useless loss of precision when drawing. + * + * The offset must be added to the drawn coordinates, and substracted from the computation + * \attention the result of pointUnderPixel is the real item translated by the offset. + * + */ + void setOffset(qglviewer::Vec offset); + + /*! + * returns the offset of the scene. + * \see `setOffset()` + */ + qglviewer::Vec offset()const; + +public Q_SLOTS: + void setFullScreen(bool fullScreen = true); + void setStereoDisplay(bool stereo = true); + /*! Toggles the state of isFullScreen(). See also setFullScreen(). */ + void toggleFullScreen() { setFullScreen(!isFullScreen()); } + /*! Toggles the state of displaysInStereo(). See setStereoDisplay(). */ + void toggleStereoDisplay() { setStereoDisplay(!stereo_); } + void toggleCameraMode(); + +protected: + bool cameraIsInRotateMode() const; + //@} + + /*! @name Display methods */ + //@{ +public: + void drawArrow(double r, double R, int prec, + qglviewer::Vec from, qglviewer::Vec to, qglviewer::Vec color, std::vector &data); + void drawAxis(qreal l = 1.0); + void drawGrid(qreal size= 1.0, int nbSubdivisions = 10); + + virtual void startScreenCoordinatesSystem(bool upward = false) const; + virtual void stopScreenCoordinatesSystem() const; + + void drawText(int x, int y, const QString &text, const QFont &fnt = QFont()); + void displayMessage(const QString &message, int delay = 2000); + +protected: + virtual void drawLight(GLenum light, qreal scale = 1.0) const; + +protected: + void displayFPS(); + + +//@} + +#ifdef DOXYGEN + /*! @name Useful inherited methods */ + //@{ +public: + /*! Returns viewer's widget width (in pixels). See QOpenGLWidget + * documentation. */ + int width() const; + /*! Returns viewer's widget height (in pixels). See QOpenGLWidget + * documentation. */ + int height() const; + /*! Updates the display. Do not call draw() directly, use this method instead. + * See QOpenGLWidget documentation. */ + virtual void update(); + /*! Returns \c true if the widget has a valid GL rendering context. See + QOpenGLWidget documentation. */ + bool isValid() const; + /*! Makes this widget's rendering context the current OpenGL rendering + context. Useful with several viewers. See QOpenGLWidget documentation. */ + virtual void makeCurrent(); + /*! Returns \c true if mouseMoveEvent() is called even when no mouse button is + pressed. + + You need to setMouseTracking() to \c true in order to use MouseGrabber (see + mouseGrabber()). See details in the QWidget documentation. */ + bool hasMouseTracking() const; +public Q_SLOTS: + /*! Resizes the widget to size \p width by \p height pixels. See also width() + * and height(). */ + virtual void resize(int width, int height); + /*! Sets the hasMouseTracking() value. */ + virtual void setMouseTracking(bool enable); +#endif + + /*! @name Buffer to texture */ + //@{ +public: + GLuint bufferTextureId() const; + /*! Returns the texture coordinate corresponding to the u extremum of the + bufferTexture. + + The bufferTexture is created by copyBufferToTexture(). The texture size has + powers of two dimensions and the buffer image hence only fills a part of it. + This value corresponds to the u coordinate of the extremum right side of the + buffer image. + + Use (0,0) to (bufferTextureMaxU(), bufferTextureMaxV()) texture coordinates to + map the entire texture on a quad. */ + qreal bufferTextureMaxU() const { return bufferTextureMaxU_; } + /*! Same as bufferTextureMaxU(), but for the v texture coordinate. */ + qreal bufferTextureMaxV() const { return bufferTextureMaxV_; } +#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)) + // These methods are part of the QGLWidget public API. + // As of version 2.7.0, the use of QOpenGLWidget instead means that they have + // to be provided for backward compatibility. + void renderText(int x, int y, const QString &str, + const QFont &font = QFont()); + void renderText(double x, double y, double z, const QString &str, + const QFont &font = QFont()); +#endif + +public Q_SLOTS: + void copyBufferToTexture(GLint, GLenum = GL_NONE); + //@} + + /*! @name Animation */ + //@{ +public: + /*! Return \c true when the animation loop is started. + + During animation, an infinite loop calls animate() and draw() and then waits + for animationPeriod() milliseconds before calling animate() and draw() again. + And again. + + Use startAnimation(), stopAnimation() or toggleAnimation() to change this + value. + + See the animation example for + illustration. */ + bool animationIsStarted() const { return animationStarted_; } + /*! The animation loop period, in milliseconds. + + When animationIsStarted(), this is delay waited after draw() to call animate() + and draw() again. Default value is 40 milliseconds (25 Hz). + + This value will define the currentFPS() when animationIsStarted() (provided + that your animate() and draw() methods are fast enough). + + If you want to know the maximum possible frame rate of your machine on a given + scene, setAnimationPeriod() to \c 0, and startAnimation() (keyboard shortcut + is \c Enter). The display will then be updated as often as possible, and the + frame rate will be meaningful. + + \note This value is taken into account only the next time you call + startAnimation(). If animationIsStarted(), you should stopAnimation() first. +*/ + int animationPeriod() const { return animationPeriod_; } + +public Q_SLOTS: + /*! Sets the animationPeriod(), in milliseconds. */ + void setAnimationPeriod(int period) { animationPeriod_ = period; } + virtual void startAnimation(); + virtual void stopAnimation(); + /*! Scene animation method. + + When animationIsStarted(), this method is in charge of the scene update + before each draw(). Overload it to define how your scene evolves over time. + The time should either be regularly incremented in this method (frame-rate + independent animation) or computed from actual time (for instance using + QTime::elapsed()) for real-time animations. + + Note that KeyFrameInterpolator (which regularly updates a Frame) does + not use this method to animate a Frame, but rather rely on a QTimer + signal-slot mechanism. + + See the animation example for an + illustration. */ + virtual void animate() { Q_EMIT animateNeeded(); } + /*! Calls startAnimation() or stopAnimation(), depending on + * animationIsStarted(). */ + void toggleAnimation() { + if (animationIsStarted()) + stopAnimation(); + else + startAnimation(); + } + //@} +public: + /*! + * Prompt a configuration dialog and takes a snapshot. + */ + void saveSnapshot(); + +public: +Q_SIGNALS: + /*! Signal emitted by the default init() method. + + Connect this signal to the methods that need to be called to initialize your + viewer or overload init(). */ + void viewerInitialized(); + + /*! Signal emitted by the default draw() method. + + Connect this signal to your main drawing method or overload draw(). See the callback example for an illustration. */ + void drawNeeded(); + + /*! Signal emitted at the end of the QGLViewer::paintGL() method, when frame + is drawn. + + Can be used to notify an image grabbing process that the image is ready. */ + void drawFinished(bool automatic); + + /*! Signal emitted by the default animate() method. + + Connect this signal to your scene animation method or overload animate(). */ + void animateNeeded(); + + /*! Signal emitted by the default QGLViewer::help() method. + + Connect this signal to your own help method or overload help(). */ + void helpRequired(); + + /*! This signal is emitted whenever axisIsDrawn() changes value. */ + void axisIsDrawnChanged(bool drawn); + /*! This signal is emitted whenever gridIsDrawn() changes value. */ + void gridIsDrawnChanged(bool drawn); + /*! This signal is emitted whenever FPSIsDisplayed() changes value. */ + void FPSIsDisplayedChanged(bool displayed); + /*! This signal is emitted whenever textIsEnabled() changes value. */ + void textIsEnabledChanged(bool enabled); + /*! This signal is emitted whenever cameraIsEdited() changes value.. */ + void cameraIsEditedChanged(bool edited); + /*! This signal is emitted whenever displaysInStereo() changes value. */ + void stereoChanged(bool on); + /*! Signal emitted by select(). + + Connect this signal to your selection method or overload select(), or more + probably simply drawWithNames(). */ + void pointSelected(const QMouseEvent *e); + + /*! Signal emitted by setMouseGrabber() when the mouseGrabber() is changed. + + \p mouseGrabber is a pointer to the new MouseGrabber. Note that this signal is + emitted with a \c NULL parameter each time a MouseGrabber stops grabbing + mouse. */ + void mouseGrabberChanged(qglviewer::MouseGrabber *mouseGrabber); + + /*! @name Help window */ + //@{ +public: + /*! Returns the QString displayed in the help() window main tab. + + Overload this method to define your own help string, which should shortly + describe your application and explain how it works. Rich-text (HTML) tags can + be used (see QStyleSheet() documentation for available tags): \code QString + myViewer::helpString() const + { + QString text("

M y V i e w e r

"); + text += "Displays a Scene using OpenGL. Move the camera using the + mouse."; return text; + } + \endcode + + See also mouseString() and keyboardString(). */ + virtual QString helpString() const { return tr("No help available."); } + + virtual QString mouseString() const; + virtual QString keyboardString() const; + +public Q_SLOTS: + virtual void help(); + virtual void aboutQGLViewer(); + +protected: + /*! Returns a pointer to the help widget. + + Use this only if you want to directly modify the help widget. Otherwise use + helpString(), setKeyDescription() and setMouseBindingDescription() to + customize the text displayed in the help window tabs. */ + QTabWidget *helpWidget() { return helpWidget_; } + //@} + + /*! @name Drawing methods */ + //@{ +protected: + virtual void resizeGL(int width, int height); + virtual void initializeGL(); + + /*! Initializes the viewer OpenGL context. + + This method is called before the first drawing and should be overloaded to + initialize some of the OpenGL flags. The default implementation is empty. See + initializeGL(). + + Typical usage include camera() initialization (showEntireScene()), previous + viewer state restoration (restoreStateFromFile()), OpenGL state modification + and display list creation. + + Note that initializeGL() modifies the standard OpenGL context. These values + can be restored back in this method. + + \attention You should not call updateGL() (or any method that calls it) in + this method, as it will result in an infinite loop. The different QGLViewer + set methods (setAxisIsDrawn(), setFPSIsDisplayed()...) are protected against + this problem and can safely be called. + + \note All the OpenGL specific initializations must be done in this method: the + OpenGL context is not yet available in your viewer constructor. */ + virtual void init() { Q_EMIT viewerInitialized(); } + + virtual void paintGL(); + virtual void preDraw(); + virtual void preDrawStereo(bool leftBuffer = true); + + /*! The core method of the viewer, that draws the scene. + + If you build a class that inherits from QGLViewer, this is the method you want + to overload. See the simpleViewer + example for an illustration. + + The camera modelView matrix set in preDraw() converts from the world to the + camera coordinate systems. Vertices given in draw() can then be considered as + being given in the world coordinate system. The camera is moved in this world + using the mouse. This representation is much more intuitive than the default + camera-centric OpenGL standard. + + \attention The \c GL_PROJECTION matrix should not be modified by this method, + to correctly display visual hints (axis, grid, FPS...) in postDraw(). Use + push/pop or call camera()->loadProjectionMatrix() at the end of draw() if you + need to change the projection matrix (unlikely). On the other hand, the \c + GL_MODELVIEW matrix can be modified and left in a arbitrary state. */ + virtual void draw() {} + virtual void fastDraw(); + virtual void postDraw(); + //@} + + /*! @name Mouse, keyboard and event handlers */ + //@{ +protected: + virtual void mousePressEvent(QMouseEvent *); + virtual void mouseMoveEvent(QMouseEvent *); + virtual void mouseReleaseEvent(QMouseEvent *); + virtual void mouseDoubleClickEvent(QMouseEvent *); + virtual void wheelEvent(QWheelEvent *); + virtual void keyPressEvent(QKeyEvent *); + virtual void keyReleaseEvent(QKeyEvent *); + virtual void timerEvent(QTimerEvent *); + virtual void closeEvent(QCloseEvent *); + //@} + + /*! @name Object selection */ + //@{ +public: + /*! Returns the name (an integer value) of the entity that was last selected + by select(). This value is set by endSelection(). See the select() + documentation for details. + + As a convention, this method returns -1 if the selectBuffer() was empty, + meaning that no object was selected. + + Return value is -1 before the first call to select(). This value is modified + using setSelectedName(). */ + int selectedName() const { return selectedObjectId_; } + /*! Returns the selectBuffer() size. + + See the select() documentation for details. Use setSelectBufferSize() to + change this value. + + Default value is 4000 (i.e. 1000 objects in selection region, since each + object pushes 4 values). This size should be over estimated to prevent a + buffer overflow when many objects are drawn under the mouse cursor. */ + int selectBufferSize() const { return selectBufferSize_; } + + /*! Returns the width (in pixels) of a selection frustum, centered on the + mouse cursor, that is used to select objects. + + The height of the selection frustum is defined by selectRegionHeight(). + + The objects that will be drawn in this region by drawWithNames() will be + recorded in the selectBuffer(). endSelection() then analyzes this buffer and + setSelectedName() to the name of the closest object. See the gluPickMatrix() + documentation for details. + + The default value is 3, which is adapted to standard applications. A smaller + value results in a more precise selection but the user has to be careful for + small feature selection. + + See the multiSelect example for an + illustration. */ + int selectRegionWidth() const { return selectRegionWidth_; } + /*! See the selectRegionWidth() documentation. Default value is 3 pixels. */ + int selectRegionHeight() const { return selectRegionHeight_; } + + /*! Returns a pointer to an array of \c GLuint. + + This buffer is used by the \c GL_SELECT mode in select() to perform object + selection. The buffer size can be modified using setSelectBufferSize(). If you + overload endSelection(), you will analyze the content of this buffer. See the + \c glSelectBuffer() man page for details. */ + GLuint *selectBuffer() { return selectBuffer_; } + +public Q_SLOTS: + virtual void select(const QMouseEvent *event); + virtual void select(const QPoint &point); + + void setSelectBufferSize(int size); + /*! Sets the selectRegionWidth(). */ + void setSelectRegionWidth(int width) { selectRegionWidth_ = width; } + /*! Sets the selectRegionHeight(). */ + void setSelectRegionHeight(int height) { selectRegionHeight_ = height; } + /*! Set the selectedName() value. + + Used in endSelection() during a selection. You should only call this method + if you overload the endSelection() method. */ + void setSelectedName(int id) { selectedObjectId_ = id; } + +protected: + virtual void beginSelection(const QPoint &point); + /*! This method is called by select() and should draw selectable entities. + + Default implementation is empty. Overload and draw the different elements of +your scene you want to be able to select. The default select() implementation +relies on the \c GL_SELECT, and requires that each selectable element is drawn +within a \c glPushName() - \c glPopName() block. A typical usage would be (see +the select example): \code void +Viewer::drawWithNames() { for (int i=0; idraw(); + glPopName(); + } +} +\endcode + + The resulting selected name is computed by endSelection(), which +setSelectedName() to the integer id pushed by this method (a value of -1 means +no selection). Use selectedName() to update your selection, probably in the +postSelection() method. + + \attention If your selected objects are points, do not use \c +glBegin(GL_POINTS); and \c glVertex3fv() in the above \c draw() method (not +compatible with raster mode): use \c glRasterPos3fv() instead. */ + virtual void drawWithNames() {} + virtual void endSelection(const QPoint &point); + /*! This method is called at the end of the select() procedure. It should + finalize the selection process and update the data + structure/interface/computation/display... according to the newly selected + entity. + + The default implementation is empty. Overload this method if needed, and use + selectedName() to retrieve the selected entity name (returns -1 if no object + was selected). See the select example + for an illustration. */ + virtual void postSelection(const QPoint &point) { Q_UNUSED(point); } + //@} + + /*! @name Keyboard customization */ + //@{ +public: + unsigned int shortcut(qglviewer::KeyboardAction action) const; + + ::Qt::Key pathKey(unsigned int index) const; + ::Qt::KeyboardModifiers addKeyFrameKeyboardModifiers() const; + ::Qt::KeyboardModifiers playPathKeyboardModifiers() const; + +public Q_SLOTS: + void setShortcut(qglviewer::KeyboardAction action, unsigned int key); + + void setKeyDescription(unsigned int key, QString description); + void clearShortcuts(); + +// Key Frames shortcut keys + + virtual void setPathKey(int key, unsigned int index = 0); + virtual void setPlayPathKeyboardModifiers(::Qt::KeyboardModifiers modifiers); + virtual void setAddKeyFrameKeyboardModifiers(::Qt::KeyboardModifiers modifiers); + //@} + +public: + /*! @name Mouse customization */ + //@{ + + qglviewer::MouseAction mouseAction(::Qt::Key key, ::Qt::KeyboardModifiers modifiers, + ::Qt::MouseButton button) const; + int mouseHandler(::Qt::Key key, ::Qt::KeyboardModifiers modifiers, + ::Qt::MouseButton button) const; + + void getMouseActionBinding(qglviewer::MouseHandler handler, qglviewer::MouseAction action, + bool withConstraint, ::Qt::Key &key, + ::Qt::KeyboardModifiers &modifiers, + ::Qt::MouseButton &button) const; + + qglviewer::ClickAction clickAction(::Qt::Key key, ::Qt::KeyboardModifiers modifiers, + ::Qt::MouseButton button, bool doubleClick = false, + ::Qt::MouseButtons buttonsBefore = ::Qt::NoButton) const; + + void getClickActionBinding(qglviewer::ClickAction action, ::Qt::Key &key, + ::Qt::KeyboardModifiers &modifiers, + ::Qt::MouseButton &button, bool &doubleClick, + ::Qt::MouseButtons &buttonsBefore) const; + + qglviewer::MouseAction wheelAction(::Qt::Key key, ::Qt::KeyboardModifiers modifiers) const; + int wheelHandler(::Qt::Key key, ::Qt::KeyboardModifiers modifiers) const; + + void getWheelActionBinding(qglviewer::MouseHandler handler, qglviewer::MouseAction action, + bool withConstraint, ::Qt::Key &key, + ::Qt::KeyboardModifiers &modifiers) const; + +public Q_SLOTS: + + void setMouseBinding(::Qt::KeyboardModifiers modifiers, ::Qt::MouseButton buttons, + qglviewer::MouseHandler handler, qglviewer::MouseAction action, + bool withConstraint = true); + void setMouseBinding(::Qt::KeyboardModifiers modifiers, ::Qt::MouseButton button, + qglviewer::ClickAction action, bool doubleClick = false, + ::Qt::MouseButtons buttonsBefore = ::Qt::NoButton); + void setWheelBinding(::Qt::KeyboardModifiers modifiers, qglviewer::MouseHandler handler, + qglviewer::MouseAction action, bool withConstraint = true); + void + setMouseBindingDescription(::Qt::KeyboardModifiers modifiers, + ::Qt::MouseButton button, QString description, + bool doubleClick = false, + ::Qt::MouseButtons buttonsBefore = ::Qt::NoButton); + + void setMouseBinding(::Qt::Key key, ::Qt::KeyboardModifiers modifiers, + ::Qt::MouseButton buttons, qglviewer::MouseHandler handler, + qglviewer::MouseAction action, bool withConstraint = true); + void setMouseBinding(::Qt::Key key, ::Qt::KeyboardModifiers modifiers, + ::Qt::MouseButton button, qglviewer::ClickAction action, + bool doubleClick = false, + ::Qt::MouseButtons buttonsBefore = ::Qt::NoButton); + void setWheelBinding(::Qt::Key key, ::Qt::KeyboardModifiers modifiers, + qglviewer::MouseHandler handler, qglviewer::MouseAction action, + bool withConstraint = true); + void + setMouseBindingDescription(::Qt::Key key, ::Qt::KeyboardModifiers modifiers, + ::Qt::MouseButton button, QString description, + bool doubleClick = false, + ::Qt::MouseButtons buttonsBefore = ::Qt::NoButton); + + void clearMouseBindings(); + +protected: + static QString mouseActionString(qglviewer::MouseAction ma); + static QString clickActionString(qglviewer::ClickAction ca); + //@} + + /*! @name State persistence */ + //@{ +public: + QString stateFileName() const; + virtual QDomElement domElement(const QString &name, + QDomDocument &document) const; + +public Q_SLOTS: + virtual void initFromDOMElement(const QDomElement &element); + virtual void saveStateToFile(); // cannot be const because of QMessageBox + virtual bool restoreStateFromFile(); + + /*! Defines the stateFileName() used by saveStateToFile() and + restoreStateFromFile(). + + The file name can have an optional prefix directory (no prefix meaning + current directory). If the directory does not exist, it will be created by + saveStateToFile(). + + \code + // Name depends on the displayed 3D model. Saved in current directory. + setStateFileName(3DModelName() + ".xml"); + + // Files are stored in a dedicated directory under user's home directory. + setStateFileName(QDir::homeDirPath + "/.config/myApp.xml"); + \endcode */ + void setStateFileName(const QString &name) { stateFileName_ = name; } + + +protected: + static void saveStateToFileForAllViewers(); + //@} + + /*! @name QGLViewer pool */ + //@{ +public: + /*! Returns a \c QList that contains pointers to all the created QGLViewers. + Note that this list may contain \c NULL pointers if the associated viewer + has been deleted. + + Can be useful to apply a method or to connect a signal to all the viewers: + \code + foreach (QGLViewer* viewer, QGLViewer::QGLViewerPool()) + connect(myObject, SIGNAL(IHaveChangedSignal()), viewer, SLOT(update())); + \endcode +*/ + static QList &QGLViewerPool(); + + /*! Returns the index of the QGLViewer \p viewer in the QGLViewerPool(). This + index in unique and can be used to identify the different created QGLViewers + (see stateFileName() for an application example). + + When a QGLViewer is deleted, the QGLViewers' indexes are preserved and NULL is + set for that index. When a QGLViewer is created, it is placed in the first + available position in that list. Returns -1 if the QGLViewer could not be + found (which should not be possible). */ + static int QGLViewerIndex(const QGLViewer *const viewer) { + return QGLViewer::QGLViewerPool().indexOf(const_cast(viewer)); + } +//@} + +#ifndef DOXYGEN + /*! @name Visual hints */ + //@{ +public: + virtual void setVisualHintsMask(int mask, int delay = 2000); + virtual void drawVisualHints(); + +public Q_SLOTS: + virtual void resetVisualHints(); +//@} +#endif + +private Q_SLOTS: + // Patch for a Qt bug with fullScreen on startup + void delayedFullScreen() { + move(prevPos_); + setFullScreen(); + } + void hideMessage(); + +private: + // Copy constructor and operator= are declared private and undefined + // Prevents everyone from trying to use them + QGLViewer(const QGLViewer &v); + QGLViewer &operator=(const QGLViewer &v); + +protected: + // Set parameters to their default values. Called by the constructors. + void defaultConstructor(); + + void handleKeyboardAction(qglviewer::KeyboardAction id); + + // C a m e r a + qglviewer::Camera *camera_; + bool cameraIsEdited_; + qreal previousCameraZClippingCoefficient_; + unsigned int previousPathId_; // double key press recognition + void connectAllCameraKFIInterpolatedSignals(bool connection = true); + + // C o l o r s + QColor backgroundColor_, foregroundColor_; + + // D i s p l a y f l a g s + bool axisIsDrawn_; // world axis + bool gridIsDrawn_; // world XY grid + bool FPSIsDisplayed_; // Frame Per Seconds + bool textIsEnabled_; // drawText() actually draws text or not + bool stereo_; // stereo display + bool fullScreen_; // full screen mode + QPoint prevPos_; // Previous window position, used for full screen mode + + // A n i m a t i o n + bool animationStarted_; // animation mode started + int animationPeriod_; // period in msecs + int animationTimerId_; + + // F P S d i s p l a y + QTime fpsTime_; + unsigned int fpsCounter_; + QString fpsString_; + qreal f_p_s_; + + // M e s s a g e s + QString message_; + bool displayMessage_; + QTimer messageTimer_; + + // M a n i p u l a t e d f r a m e + qglviewer::ManipulatedFrame *manipulatedFrame_; + bool manipulatedFrameIsACamera_; + + // M o u s e G r a b b e r + qglviewer::MouseGrabber *mouseGrabber_; + bool mouseGrabberIsAManipulatedFrame_; + bool mouseGrabberIsAManipulatedCameraFrame_; + QMap disabledMouseGrabbers_; + + // S e l e c t i o n + int selectRegionWidth_, selectRegionHeight_; + int selectBufferSize_; + GLuint *selectBuffer_; + int selectedObjectId_; + + // V i s u a l h i n t s + int visualHint_; + + // S h o r t c u t k e y s + void setDefaultShortcuts(); + QString cameraPathKeysString() const; + QMap keyboardActionDescription_; + QMap keyboardBinding_; + QMap keyDescription_; + + // K e y F r a m e s s h o r t c u t s + QMap< ::Qt::Key, unsigned int> pathIndex_; + ::Qt::KeyboardModifiers addKeyFrameKeyboardModifiers_, + playPathKeyboardModifiers_; + + // B u f f e r T e x t u r e + GLuint bufferTextureId_; + qreal bufferTextureMaxU_, bufferTextureMaxV_; + int bufferTextureWidth_, bufferTextureHeight_; + unsigned int previousBufferTextureFormat_; + int previousBufferTextureInternalFormat_; + +#ifndef DOXYGEN + // M o u s e a c t i o n s + struct MouseActionPrivate { + qglviewer::MouseHandler handler; + qglviewer::MouseAction action; + bool withConstraint; + }; + + // M o u s e b i n d i n g s + struct MouseBindingPrivate { + const ::Qt::KeyboardModifiers modifiers; + const ::Qt::MouseButton button; + const ::Qt::Key key; + + MouseBindingPrivate(::Qt::KeyboardModifiers m, ::Qt::MouseButton b, ::Qt::Key k) + : modifiers(m), button(b), key(k) {} + + // This sort order is used in mouseString() to display sorted mouse bindings + bool operator<(const MouseBindingPrivate &mbp) const { + if (key != mbp.key) + return key < mbp.key; + if (modifiers != mbp.modifiers) + return modifiers < mbp.modifiers; + return button < mbp.button; + } + }; + + // W h e e l b i n d i n g s + struct WheelBindingPrivate { + const ::Qt::KeyboardModifiers modifiers; + const ::Qt::Key key; + + WheelBindingPrivate(::Qt::KeyboardModifiers m, ::Qt::Key k) + : modifiers(m), key(k) {} + + // This sort order is used in mouseString() to display sorted wheel bindings + bool operator<(const WheelBindingPrivate &wbp) const { + if (key != wbp.key) + return key < wbp.key; + return modifiers < wbp.modifiers; + } + }; + + // C l i c k b i n d i n g s + struct ClickBindingPrivate { + const ::Qt::KeyboardModifiers modifiers; + const ::Qt::MouseButton button; + const bool doubleClick; + const ::Qt::MouseButtons + buttonsBefore; // only defined when doubleClick is true + const ::Qt::Key key; + + ClickBindingPrivate(::Qt::KeyboardModifiers m, ::Qt::MouseButton b, bool dc, + ::Qt::MouseButtons bb, ::Qt::Key k) + : modifiers(m), button(b), doubleClick(dc), buttonsBefore(bb), key(k) {} + + // This sort order is used in mouseString() to display sorted mouse bindings + bool operator<(const ClickBindingPrivate &cbp) const { + if (key != cbp.key) + return key < cbp.key; + if (buttonsBefore != cbp.buttonsBefore) + return buttonsBefore < cbp.buttonsBefore; + if (modifiers != cbp.modifiers) + return modifiers < cbp.modifiers; + if (button != cbp.button) + return button < cbp.button; + return doubleClick != cbp.doubleClick; + } + }; +#endif + static QString formatClickActionPrivate(ClickBindingPrivate cbp); + static bool isValidShortcutKey(int key); + + QMap mouseDescription_; + + void setDefaultMouseBindings(); + void performClickAction(qglviewer::ClickAction ca, const QMouseEvent *const e); + QMap mouseBinding_; + QMap wheelBinding_; + QMap clickBinding_; + ::Qt::Key currentlyPressedKey_; + + // S t a t e F i l e + QString stateFileName_; + + // H e l p w i n d o w + QTabWidget *helpWidget_; + + //internal drawing buffers + enum VBO + { + Grid = 0, + Grid_axis, + Axis, + Pivot_point, + VBO_size + }; + enum VAO + { + GRID = 0, + GRID_AXIS, + AXIS, + PIVOT_POINT, + VAO_size + }; + QOpenGLShaderProgram rendering_program; + QOpenGLShaderProgram rendering_program_light; + QOpenGLVertexArrayObject vaos[VAO_size]; + QVector vbos; + std::size_t grid_size; + std::size_t g_axis_size; + std::size_t axis_size; + + //S n a p s h o t + QImage* takeSnapshot(qglviewer::SnapShotBackground background_color, + QSize finalSize, double oversampling, bool expand); + + //Internal Projection Matrix + + // O f f s e t + qglviewer::Vec _offset; + + //C o n t e x t + bool is_ogl_4_3; +public: + //! Is used to know if the openGL context is 4.3 or 2.1. + //! @returns `true` if the context is 4.3. + //! @returns `false` if the context is 2.1. + bool isOpenGL_4_3()const {return is_ogl_4_3; } + +}; + +} //end CGAL + + +#ifdef CGAL_HEADER_ONLY +#include +#endif // CGAL_HEADER_ONLY + +#endif // QGLVIEWER_QGLVIEWER_H diff --git a/GraphicsView/include/CGAL/Qt/qglviewer_impl.h b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h new file mode 100644 index 00000000000..e6a530dd845 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h @@ -0,0 +1,4085 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 + +#ifdef CGAL_HEADER_ONLY +#define CGAL_INLINE_FUNCTION inline + +#include + +#else +#define CGAL_INLINE_FUNCTION +#endif + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace CGAL{ +// Static private variable +CGAL_INLINE_FUNCTION +QList &CGAL::QGLViewer::QGLViewerPool() { + static QList QGLViewerPool_; + void* p = qApp->property("qglviewer pool").value(); + if(p == 0) { + p = (void*)(&QGLViewerPool_); + qApp->setProperty("qglviewer pool", QVariant::fromValue(p)); + } + return *static_cast * >(p); +} + +/*! \mainpage + +libCGAL::QGLViewer is a free C++ library based on Qt that enables the quick creation +of OpenGL 3D viewers. It features a powerful camera trackball and simple +applications simply require an implementation of the draw() method. +This makes it a tool of choice for OpenGL beginners and assignments. It provides +mouse manipulated frames, stereo display, interpolated +keyFrames, object selection, and much more. It is fully +customizable and easy to extend to create complex applications, with a possible +Qt GUI. + +libCGAL::QGLViewer is not a 3D viewer that can be used directly to view 3D +scenes in various formats. It is more likely to be the starting point for the +coding of such a viewer. + +libCGAL::QGLViewer is based on the Qt toolkit and hence compiles on any architecture +(Unix-Linux, Mac, Windows, ...). Full reference documentation and many examples +are provided. + +See the project main page for details on the project and installation steps. */ + +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::defaultConstructor() { + + int poolIndex = CGAL::QGLViewer::QGLViewerPool().indexOf(NULL); + setFocusPolicy(::Qt::StrongFocus); + + if (poolIndex >= 0) + CGAL::QGLViewer::QGLViewerPool().replace(poolIndex, this); + else + CGAL::QGLViewer::QGLViewerPool().append(this); + camera_ = new qglviewer::Camera(this); + setCamera(camera()); + + setDefaultShortcuts(); + setDefaultMouseBindings(); + + fpsTime_.start(); + fpsCounter_ = 0; + f_p_s_ = 0.0; + fpsString_ = tr("%1Hz", "Frames per seconds, in Hertz").arg("?"); + visualHint_ = 0; + previousPathId_ = 0; + // prevPos_ is not initialized since pos() is not meaningful here. + // It will be set when setFullScreen(false) is called after + // setFullScreen(true) + + // #CONNECTION# default values in initFromDOMElement() + manipulatedFrame_ = NULL; + manipulatedFrameIsACamera_ = false; + mouseGrabberIsAManipulatedFrame_ = false; + mouseGrabberIsAManipulatedCameraFrame_ = false; + displayMessage_ = false; + connect(&messageTimer_, SIGNAL(timeout()), SLOT(hideMessage())); + messageTimer_.setSingleShot(true); + helpWidget_ = NULL; + setMouseGrabber(NULL); + + setSceneRadius(1.0); + showEntireScene(); + setStateFileName(".qglviewer.xml"); + + // #CONNECTION# default values in initFromDOMElement() + setAxisIsDrawn(false); + setGridIsDrawn(false); + setFPSIsDisplayed(false); + setCameraIsEdited(false); + setTextIsEnabled(true); + setStereoDisplay(false); + // Make sure move() is not called, which would call initializeGL() + fullScreen_ = false; + setFullScreen(false); + + animationTimerId_ = 0; + stopAnimation(); + setAnimationPeriod(40); // 25Hz + + selectBuffer_ = NULL; + setSelectBufferSize(4 * 1000); + setSelectRegionWidth(3); + setSelectRegionHeight(3); + setSelectedName(-1); + + bufferTextureId_ = 0; + bufferTextureMaxU_ = 0.0; + bufferTextureMaxV_ = 0.0; + bufferTextureWidth_ = 0; + bufferTextureHeight_ = 0; + previousBufferTextureFormat_ = 0; + previousBufferTextureInternalFormat_ = 0; + currentlyPressedKey_ = ::Qt::Key(0); + + setAttribute(::Qt::WA_NoSystemBackground); + axisIsDrawn_ = true; + + _offset = CGAL::qglviewer::Vec(0,0,0); +} + +CGAL_INLINE_FUNCTION +CGAL::QGLViewer::QGLViewer(QWidget *parent, + ::Qt::WindowFlags flags) + : QOpenGLWidget(parent, flags) { + defaultConstructor(); +} + +/*! Virtual destructor. + +The viewer is replaced by \c NULL in the QGLViewerPool() (in order to preserve +other viewer's indexes) and allocated memory is released. The camera() is +deleted and should be copied before if it is shared by an other viewer. */ +CGAL_INLINE_FUNCTION +CGAL::QGLViewer::~QGLViewer() { + // See closeEvent comment. Destructor is called (and not closeEvent) only when + // the widget is embedded. Hence we saveToFile here. It is however a bad idea + // if virtual domElement() has been overloaded ! if (parent()) + // saveStateToFileForAllViewers(); + + CGAL::QGLViewer::QGLViewerPool().replace(CGAL::QGLViewer::QGLViewerPool().indexOf(this), + NULL); + + camera()->deleteLater(); + delete[] selectBuffer_; + if (helpWidget()) { + // Needed for Qt 4 which has no main widget. + helpWidget()->close(); + delete helpWidget_; + } +} + + +/*! Initializes the CGAL::QGLViewer OpenGL context and then calls user-defined init(). + +This method is automatically called once, before the first call to paintGL(). + +Overload init() instead of this method to modify viewer specific OpenGL state. + +If a 4.3 context could not be set, a 2.1 context will be used instead. + \see `isOpenGL_4_3()` +*/ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::initializeGL() { + QSurfaceFormat format; + format.setDepthBufferSize(24); + format.setStencilBufferSize(8); + format.setVersion(4,3); + format.setProfile(QSurfaceFormat::CompatibilityProfile); + format.setSamples(0); + format.setOption(QSurfaceFormat::DebugContext); + context()->setFormat(format); + bool created = context()->create(); + if(!created || context()->format().profile() != QSurfaceFormat::CompatibilityProfile) { + // impossible to get a 4.3 compatibility profile, retry with 2.0 + format.setVersion(2,1); + context()->setFormat(format); + created = context()->create(); + is_ogl_4_3 = false; + } + else + { + is_ogl_4_3 = true; + } + makeCurrent(); + QOpenGLFunctions_2_1::initializeOpenGLFunctions(); + // Default colors + setForegroundColor(QColor(180, 180, 180)); + setBackgroundColor(QColor(51, 51, 51)); + + // Clear the buffer where we're going to draw + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + // Calls user defined method. Default emits a signal. + init(); + + //OpenGL buffers and programs initialization + for(int i=0; i= 0; --view) { + // Clears screen, set model view matrix with shifted matrix for ith buffer + preDrawStereo(view); + // Used defined method. Default is empty + if (camera()->frame()->isManipulated()) + fastDraw(); + else + draw(); + postDraw(); + } + } else { + // Clears screen, set model view matrix... + preDraw(); + // Used defined method. Default calls draw() + if (camera()->frame()->isManipulated()) + fastDraw(); + else + draw(); + // Add visual hints: axis, camera, grid... + postDraw(); + } + Q_EMIT drawFinished(true); +} + +/*! Sets OpenGL state before draw(). + +Default behavior clears screen and sets the projection and modelView matrices: +\code +glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + +camera()->loadProjectionMatrix(); +camera()->loadModelViewMatrix(); +\endcode + +Emits the drawNeeded() signal once this is done (see the callback example). */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::preDraw() { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // GL_PROJECTION matrix + camera()->loadProjectionMatrix(); + // GL_MODELVIEW matrix + camera()->loadModelViewMatrix(); + + Q_EMIT drawNeeded(); +} + +/*! Called after draw() to draw viewer visual hints. + +Default implementation displays axis, grid, FPS... when the respective flags are +sets. + +See the multiSelect and thumbnail examples for an +overloading illustration. + +The GLContext (color, LIGHTING, BLEND...) is \e not modified by this method, so +that in draw(), the user can rely on the OpenGL context he defined. Respect this +convention (by pushing/popping the different attributes) if you overload this +method. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::postDraw() { + // Pivot point, line when camera rolls, zoom region + if (gridIsDrawn()) { + glLineWidth(1.0); + drawGrid(camera()->sceneRadius()); + } + if (axisIsDrawn()) { + glLineWidth(2.0); + drawAxis(1.0); + } + + + drawVisualHints(); + // FPS computation + const unsigned int maxCounter = 20; + if (++fpsCounter_ == maxCounter) { + f_p_s_ = 1000.0 * maxCounter / fpsTime_.restart(); + fpsString_ = tr("%1Hz", "Frames per seconds, in Hertz") + .arg(f_p_s_, 0, 'f', ((f_p_s_ < 10.0) ? 1 : 0)); + fpsCounter_ = 0; + } + + // Restore foregroundColor + GLfloat color[4]; + color[0] = GLfloat(foregroundColor().red()) / 255.0f; + color[1] = GLfloat(foregroundColor().green()) / 255.0f; + color[2] = GLfloat(foregroundColor().blue()) / 255.0f; + color[3] = 1.0f; + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + + if (FPSIsDisplayed()) + displayFPS(); + if (displayMessage_) + drawText(10, height() - 10, message_); + +} + +/*! Called before draw() (instead of preDraw()) when viewer displaysInStereo(). + +Same as preDraw() except that the glDrawBuffer() is set to \c GL_BACK_LEFT or \c +GL_BACK_RIGHT depending on \p leftBuffer, and it uses +CGAL::qglviewer::Camera::loadProjectionMatrixStereo() and +CGAL::qglviewer::Camera::loadModelViewMatrixStereo() instead. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::preDrawStereo(bool leftBuffer) { + // Set buffer to draw in + // Seems that SGI and Crystal Eyes are not synchronized correctly ! + // That's why we don't draw in the appropriate buffer... + if (!leftBuffer) + glDrawBuffer(GL_BACK_LEFT); + else + glDrawBuffer(GL_BACK_RIGHT); + + // Clear the buffer where we're going to draw + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + // GL_PROJECTION matrix + camera()->loadProjectionMatrixStereo(leftBuffer); + // GL_MODELVIEW matrix + camera()->loadModelViewMatrixStereo(leftBuffer); + + Q_EMIT drawNeeded(); +} + +/*! Draws a simplified version of the scene to guarantee interactive camera +displacements. + +This method is called instead of draw() when the CGAL::qglviewer::Camera::frame() is +CGAL::qglviewer::ManipulatedCameraFrame::isManipulated(). Default implementation +simply calls draw(). + +Overload this method if your scene is too complex to allow for interactive +camera manipulation. See the fastDraw +example for an illustration. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::fastDraw() { draw(); } + +/*! Starts (\p edit = \c true, default) or stops (\p edit=\c false) the edition +of the camera(). + +Current implementation is limited to paths display. Get current state using +cameraIsEdited(). + +\attention This method sets the CGAL::qglviewer::Camera::zClippingCoefficient() to 5.0 +when \p edit is \c true, so that the Camera paths (see +CGAL::qglviewer::Camera::keyFrameInterpolator()) are not clipped. It restores the +previous value when \p edit is \c false. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setCameraIsEdited(bool edit) { + cameraIsEdited_ = edit; + if (edit) { + previousCameraZClippingCoefficient_ = camera()->zClippingCoefficient(); + // #CONNECTION# 5.0 also used in domElement() and in initFromDOMElement(). + camera()->setZClippingCoefficient(5.0); + } else + camera()->setZClippingCoefficient(previousCameraZClippingCoefficient_); + + Q_EMIT cameraIsEditedChanged(edit); + + update(); +} + +// Key bindings. 0 means not defined +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setDefaultShortcuts() { + // D e f a u l t a c c e l e r a t o r s + setShortcut(qglviewer::DRAW_AXIS, ::Qt::Key_A); + setShortcut(qglviewer::DRAW_GRID, ::Qt::Key_G); + setShortcut(qglviewer::DISPLAY_FPS, ::Qt::Key_F); + setShortcut(qglviewer::ENABLE_TEXT, ::Qt::SHIFT + ::Qt::Key_Question); + setShortcut(qglviewer::EXIT_VIEWER, ::Qt::Key_Escape); + setShortcut(qglviewer::CAMERA_MODE, ::Qt::Key_Space); + setShortcut(qglviewer::FULL_SCREEN, ::Qt::ALT + ::Qt::Key_Return); + setShortcut(qglviewer::STEREO, ::Qt::Key_S); + setShortcut(qglviewer::ANIMATION, ::Qt::Key_Return); + setShortcut(qglviewer::HELP, ::Qt::Key_H); + setShortcut(qglviewer::EDIT_CAMERA, ::Qt::Key_C); + setShortcut(qglviewer::MOVE_CAMERA_LEFT, ::Qt::Key_Left); + setShortcut(qglviewer::MOVE_CAMERA_RIGHT, ::Qt::Key_Right); + setShortcut(qglviewer::MOVE_CAMERA_UP, ::Qt::Key_Up); + setShortcut(qglviewer::MOVE_CAMERA_DOWN, ::Qt::Key_Down); + setShortcut(qglviewer::INCREASE_FLYSPEED, ::Qt::Key_Plus); + setShortcut(qglviewer::DECREASE_FLYSPEED, ::Qt::Key_Minus); + + keyboardActionDescription_[qglviewer::DISPLAY_FPS] = + tr("Toggles the display of the FPS", "DISPLAY_FPS action description"); + keyboardActionDescription_[qglviewer::FULL_SCREEN] = + tr("Toggles full screen display", "FULL_SCREEN action description"); + keyboardActionDescription_[qglviewer::DRAW_AXIS] = tr( + "Toggles the display of the world axis", "DRAW_AXIS action description"); + keyboardActionDescription_[qglviewer::DRAW_GRID] = + tr("Toggles the display of the XY grid", "DRAW_GRID action description"); + keyboardActionDescription_[qglviewer::CAMERA_MODE] = tr( + "Changes camera mode (observe or fly)", "CAMERA_MODE action description"); + keyboardActionDescription_[qglviewer::STEREO] = + tr("Toggles stereo display", "STEREO action description"); + keyboardActionDescription_[qglviewer::HELP] = + tr("Opens this help window", "HELP action description"); + keyboardActionDescription_[qglviewer::ANIMATION] = + tr("Starts/stops the animation", "ANIMATION action description"); + keyboardActionDescription_[qglviewer::EDIT_CAMERA] = + tr("Toggles camera paths display", + "EDIT_CAMERA action description"); // TODO change + keyboardActionDescription_[qglviewer::ENABLE_TEXT] = + tr("Toggles the display of the text", "ENABLE_TEXT action description"); + keyboardActionDescription_[qglviewer::EXIT_VIEWER] = + tr("Exits program", "EXIT_VIEWER action description"); + keyboardActionDescription_[qglviewer::MOVE_CAMERA_LEFT] = + tr("Moves camera left", "MOVE_CAMERA_LEFT action description"); + keyboardActionDescription_[qglviewer::MOVE_CAMERA_RIGHT] = + tr("Moves camera right", "MOVE_CAMERA_RIGHT action description"); + keyboardActionDescription_[qglviewer::MOVE_CAMERA_UP] = + tr("Moves camera up", "MOVE_CAMERA_UP action description"); + keyboardActionDescription_[qglviewer::MOVE_CAMERA_DOWN] = + tr("Moves camera down", "MOVE_CAMERA_DOWN action description"); + keyboardActionDescription_[qglviewer::INCREASE_FLYSPEED] = + tr("Increases fly speed", "INCREASE_FLYSPEED action description"); + keyboardActionDescription_[qglviewer::DECREASE_FLYSPEED] = + tr("Decreases fly speed", "DECREASE_FLYSPEED action description"); + + // K e y f r a m e s s h o r t c u t k e y s + setPathKey(::Qt::Key_F1, 1); + setPathKey(::Qt::Key_F2, 2); + setPathKey(::Qt::Key_F3, 3); + setPathKey(::Qt::Key_F4, 4); + setPathKey(::Qt::Key_F5, 5); + setPathKey(::Qt::Key_F6, 6); + setPathKey(::Qt::Key_F7, 7); + setPathKey(::Qt::Key_F8, 8); + setPathKey(::Qt::Key_F9, 9); + setPathKey(::Qt::Key_F10, 10); + setPathKey(::Qt::Key_F11, 11); + setPathKey(::Qt::Key_F12, 12); + + setAddKeyFrameKeyboardModifiers(::Qt::AltModifier); + setPlayPathKeyboardModifiers(::Qt::NoModifier); +} + +// M o u s e b e h a v i o r +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setDefaultMouseBindings() { + const ::Qt::KeyboardModifiers cameraKeyboardModifiers = ::Qt::NoModifier; + const ::Qt::KeyboardModifiers frameKeyboardModifiers = ::Qt::ControlModifier; + + //#CONNECTION# toggleCameraMode() + for (int handler = 0; handler < 2; ++handler) { + qglviewer::MouseHandler mh = (qglviewer::MouseHandler)(handler); + ::Qt::KeyboardModifiers modifiers = + (mh == qglviewer::FRAME) ? frameKeyboardModifiers : cameraKeyboardModifiers; + + setMouseBinding(modifiers, ::Qt::LeftButton, mh, qglviewer::ROTATE); + setMouseBinding(modifiers, ::Qt::MidButton, mh, qglviewer::ZOOM); + setMouseBinding(modifiers, ::Qt::RightButton, mh, qglviewer::TRANSLATE); + + setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, mh, qglviewer::SCREEN_ROTATE); + + setWheelBinding(modifiers, mh, qglviewer::ZOOM); + } + + // Z o o m o n r e g i o n + setMouseBinding(::Qt::ShiftModifier, ::Qt::MidButton, qglviewer::CAMERA, qglviewer::ZOOM_ON_REGION); + + // S e l e c t + setMouseBinding(::Qt::ShiftModifier, ::Qt::LeftButton, qglviewer::SELECT); + + setMouseBinding(::Qt::ShiftModifier, ::Qt::RightButton, qglviewer::RAP_FROM_PIXEL); + // D o u b l e c l i c k + setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, qglviewer::ALIGN_CAMERA, true); + setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, qglviewer::SHOW_ENTIRE_SCENE, true); + setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, qglviewer::CENTER_SCENE, true); + + setMouseBinding(frameKeyboardModifiers, ::Qt::LeftButton, qglviewer::ALIGN_FRAME, true); + // middle double click makes no sense for manipulated frame + setMouseBinding(frameKeyboardModifiers, ::Qt::RightButton, qglviewer::CENTER_FRAME, true); + + // A c t i o n s w i t h k e y m o d i f i e r s + setMouseBinding(::Qt::Key_Z, ::Qt::NoModifier, ::Qt::LeftButton, qglviewer::ZOOM_ON_PIXEL); + setMouseBinding(::Qt::Key_Z, ::Qt::NoModifier, ::Qt::RightButton, qglviewer::ZOOM_TO_FIT); + +#ifdef Q_OS_MAC + // Specific Mac bindings for touchpads. Two fingers emulate a wheelEvent which + // zooms. There is no right button available : make Option key + left emulate + // the right button. A Control+Left indeed emulates a right click (OS X system + // configuration), but it does no seem to support dragging. Done at the end to + // override previous settings. + const ::Qt::KeyboardModifiers macKeyboardModifiers = ::Qt::AltModifier; + + setMouseBinding(macKeyboardModifiers, ::Qt::LeftButton, qglviewer::CAMERA, qglviewer::TRANSLATE); + setMouseBinding(macKeyboardModifiers, ::Qt::LeftButton, qglviewer::CENTER_SCENE, true); + setMouseBinding(frameKeyboardModifiers | macKeyboardModifiers, ::Qt::LeftButton, + qglviewer::CENTER_FRAME, true); + setMouseBinding(frameKeyboardModifiers | macKeyboardModifiers, ::Qt::LeftButton, + qglviewer::FRAME, qglviewer::TRANSLATE); +#endif +} + +/*! Associates a new CGAL::qglviewer::Camera to the viewer. + +You should only use this method when you derive a new class from +CGAL::qglviewer::Camera and want to use one of its instances instead of the original +class. + +It you simply want to save and restore Camera positions, use +CGAL::qglviewer::Camera::addKeyFrameToPath() and CGAL::qglviewer::Camera::playPath() +instead. + +This method silently ignores \c NULL \p camera pointers. The calling method is +responsible for deleting the previous camera pointer in order to prevent memory +leaks if needed. + +The sceneRadius() and sceneCenter() of \p camera are set to the \e current +CGAL::QGLViewer values. + +All the \p camera CGAL::qglviewer::Camera::keyFrameInterpolator() +CGAL::qglviewer::KeyFrameInterpolator::interpolated() signals are connected to the +viewer update() slot. The connections with the previous viewer's camera are +removed. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setCamera(qglviewer::Camera *const camera) { + if (!camera) + return; + + camera->setSceneRadius(sceneRadius()); + camera->setSceneCenter(sceneCenter()); + camera->setScreenWidthAndHeight(width(), height()); + + // Disconnect current camera from this viewer. + disconnect(this->camera()->frame(), SIGNAL(manipulated()), this, + SLOT(update())); + disconnect(this->camera()->frame(), SIGNAL(spun()), this, SLOT(update())); + + // Connect camera frame to this viewer. + connect(camera->frame(), SIGNAL(manipulated()), SLOT(update())); + connect(camera->frame(), SIGNAL(spun()), SLOT(update())); + + connectAllCameraKFIInterpolatedSignals(false); + camera_ = camera; + connectAllCameraKFIInterpolatedSignals(); + + previousCameraZClippingCoefficient_ = this->camera()->zClippingCoefficient(); +} + +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::connectAllCameraKFIInterpolatedSignals(bool connection) { + for (QMap::ConstIterator + it = camera()->kfi_.begin(), + end = camera()->kfi_.end(); + it != end; ++it) { + if (connection) + connect(camera()->keyFrameInterpolator(it.key()), SIGNAL(interpolated()), + SLOT(update())); + else + disconnect(camera()->keyFrameInterpolator(it.key()), + SIGNAL(interpolated()), this, SLOT(update())); + } + + if (connection) + connect(camera()->interpolationKfi_, SIGNAL(interpolated()), + SLOT(update())); + else + disconnect(camera()->interpolationKfi_, SIGNAL(interpolated()), this, + SLOT(update())); +} + +/*! Draws a representation of \p light. + +Called in draw(), this method is useful to debug or display your light setup. +Light drawing depends on the type of light (point, spot, directional). + +The method retrieves the light setup using \c glGetLightfv. Position and define +your lights before calling this method. + +Light is drawn using its diffuse color. Disabled lights are not displayed. + +Drawing size is proportional to sceneRadius(). Use \p scale to rescale it. + +See the drawLight example for an +illustration. + +\attention You need to enable \c GL_COLOR_MATERIAL before calling this method. +\c glColor is set to the light diffuse color. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::drawLight(GLenum, qreal ) const { +} + +#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)) +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::renderText(int x, int y, const QString &str, + const QFont &font) { + QColor fontColor = QColor(0, 0, + 0, 255); + + // Render text + QPainter painter(this); + painter.setPen(fontColor); + painter.setFont(font); + painter.drawText(x, y, str); + painter.end(); +} + +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::renderText(double x, double y, double z, const QString &str, + const QFont &font) { + using CGAL::qglviewer::Vec; + const Vec proj = camera_->projectedCoordinatesOf(Vec(x, y, z)); + renderText(int(proj.x), int(proj.y), str, font); +} +#endif + +/*! Draws \p text at position \p x, \p y (expressed in screen coordinates +pixels, origin in the upper left corner of the widget). + +The default QApplication::font() is used to render the text when no \p fnt is +specified. Use QApplication::setFont() to define this default font. + +You should disable \c GL_LIGHTING and \c GL_DEPTH_TEST before this method so +that colors are properly rendered. + +This method can be used in conjunction with the +CGAL::qglviewer::Camera::projectedCoordinatesOf() method to display a text attached to +an object. In your draw() method use: \code CGAL::qglviewer::Vec screenPos = +camera()->projectedCoordinatesOf(myFrame.position()); +drawText((int)screenPos[0], (int)screenPos[1], "My Object"); +\endcode +See the screenCoordSystem +example for an illustration. + +Text is displayed only when textIsEnabled() (default). This mechanism allows the +user to conveniently remove all the displayed text with a single keyboard +shortcut. + +See also displayMessage() to drawText() for only a short amount of time. + +Use renderText(x,y,z, text) instead if you want to draw a text located + at a specific 3D position instead of 2D screen coordinates (fixed size text, +facing the camera). + +The \c GL_MODELVIEW and \c GL_PROJECTION matrices are not modified by this +method. +*/ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::drawText(int x, int y, const QString &text, const QFont &fnt) { + if (!textIsEnabled()) + return; + + renderText(x, y, text, fnt); +} + +/*! Briefly displays a message in the lower left corner of the widget. +Convenient to provide feedback to the user. + +\p message is displayed during \p delay milliseconds (default is 2 seconds) +using drawText(). + +This method should not be called in draw(). If you want to display a text in +each draw(), use drawText() instead. + +If this method is called when a message is already displayed, the new message +replaces the old one. Use setTextIsEnabled() (default shortcut is '?') to enable +or disable text (and hence messages) display. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::displayMessage(const QString &message, int delay) { + message_ = message; + displayMessage_ = true; + // Was set to single shot in defaultConstructor. + messageTimer_.start(delay); + if (textIsEnabled()) + update(); +} + +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::hideMessage() { + displayMessage_ = false; + if (textIsEnabled()) + update(); +} + +/*! Displays the averaged currentFPS() frame rate in the upper left corner of +the widget. + +update() should be called in a loop in order to have a meaningful value (this is +the case when you continuously move the camera using the mouse or when +animationIsStarted()). setAnimationPeriod(0) to make this loop as fast as +possible in order to reach and measure the maximum available frame rate. + +When FPSIsDisplayed() is \c true (default is \c false), this method is called by +postDraw() to display the currentFPS(). Use QApplication::setFont() to define +the font (see drawText()). */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::displayFPS() { + drawText(10, + int(1.5 * ((QApplication::font().pixelSize() > 0) + ? QApplication::font().pixelSize() + : QApplication::font().pointSize())), + fpsString_); +} + +/*! Modify the projection matrix so that drawing can be done directly with 2D +screen coordinates. + +Once called, the \p x and \p y coordinates passed to \c glVertex are expressed +in pixels screen coordinates. The origin (0,0) is in the upper left corner of +the widget by default. This follows the Qt standards, so that you can directly +use the \c pos() provided by for instance \c QMouseEvent. Set \p upward to \c +true to place the origin in the \e lower left corner, thus following the OpenGL +and mathematical standards. It is always possible to switch between the two +representations using \c newY = height() - \c y. + +You need to call stopScreenCoordinatesSystem() at the end of the drawing block +to restore the previous camera matrix. + +In practice, this method should be used in draw(). It sets an appropriate +orthographic projection matrix and then sets \c glMatrixMode to \c GL_MODELVIEW. + +See the screenCoordSystem, multiSelect and backgroundImage examples +for an illustration. + +You may want to disable \c GL_LIGHTING, to enable \c GL_LINE_SMOOTH or \c +GL_BLEND to draw when this method is used. + +If you want to link 2D drawings to 3D objects, use +CGAL::qglviewer::Camera::projectedCoordinatesOf() to compute the 2D projection on +screen of a 3D point (see the screenCoordSystem example). See +also drawText(). + +In this mode, you should use z values that are in the [0.0, 1.0[ range (0.0 +corresponding to the near clipping plane and 1.0 being just beyond the far +clipping plane). This interval matches the values that can be read from the +z-buffer. Note that if you use the convenient \c glVertex2i() to provide +coordinates, the implicit 0.0 z coordinate will make your drawings appear \e on +\e top of the rest of the scene. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::startScreenCoordinatesSystem(bool ) const { +} + +/*! Stops the pixel coordinate drawing block started by +startScreenCoordinatesSystem(). + +The \c GL_MODELVIEW and \c GL_PROJECTION matrices modified in +startScreenCoordinatesSystem() are restored. \c glMatrixMode is set to \c +GL_MODELVIEW. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::stopScreenCoordinatesSystem() const { +} + +/*! Overloading of the \c QObject method. + +If animationIsStarted(), calls animate() and draw(). */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::timerEvent(QTimerEvent *) { + if (animationIsStarted()) { + animate(); + update(); + } +} + +/*! Starts the animation loop. See animationIsStarted(). */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::startAnimation() { + animationTimerId_ = startTimer(animationPeriod()); + animationStarted_ = true; +} + +/*! Stops animation. See animationIsStarted(). */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::stopAnimation() { + animationStarted_ = false; + if (animationTimerId_ != 0) + killTimer(animationTimerId_); +} + +/*! Overloading of the \c QWidget method. + +Saves the viewer state using saveStateToFile() and then calls +QOpenGLWidget::closeEvent(). */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::closeEvent(QCloseEvent *e) { + // When the user clicks on the window close (x) button: + // - If the viewer is a top level window, closeEvent is called and then saves + // to file. - Otherwise, nothing happen s:( When the user press the + // EXIT_VIEWER keyboard shortcut: - If the viewer is a top level window, + // saveStateToFile() is also called - Otherwise, closeEvent is NOT called and + // keyPressEvent does the job. + + /* After tests: + E : Embedded widget + N : Widget created with new + C : closeEvent called + D : destructor called + + E N C D + y y + y n y + n y y + n n y y + + closeEvent is called iif the widget is NOT embedded. + + Destructor is called iif the widget is created on the stack + or if widget (resp. parent if embedded) is created with WDestructiveClose + flag. + + closeEvent always before destructor. + + Close using qApp->closeAllWindows or (x) is identical. + */ + + // #CONNECTION# Also done for EXIT_VIEWER in keyPressEvent(). + saveStateToFile(); + QOpenGLWidget::closeEvent(e); +} + +/*! Simple wrapper method: calls \c select(event->pos()). + +Emits \c pointSelected(e) which is useful only if you rely on the Qt signal-slot +mechanism and you did not overload CGAL::QGLViewer. If you choose to derive your own +viewer class, simply overload select() (or probably simply drawWithNames(), see +the select example) to implement your +selection mechanism. + +This method is called when you use the CGAL::QGLViewer::SELECT mouse binding(s) +(default is Shift + left button). Use setMouseBinding() to change this. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::select(const QMouseEvent *event) { + // For those who don't derive but rather rely on the signal-slot mechanism. + Q_EMIT pointSelected(event); + select(event->pos()); +} + +/*! This method performs a selection in the scene from pixel coordinates. + +It is called when the user clicks on the CGAL::QGLViewer::SELECT +CGAL::QGLViewer::ClickAction binded button(s) (default is Shift + LeftButton). + +This template method successively calls four other methods: +\code +beginSelection(point); +drawWithNames(); +endSelection(point); +postSelection(point); +\endcode + +The default implementation of these methods is as follows (see the methods' +documentation for more details): + +\arg beginSelection() sets the \c GL_SELECT mode with the appropriate picking +matrices. A rectangular frustum (of size defined by selectRegionWidth() and +selectRegionHeight()) centered on \p point is created. + +\arg drawWithNames() is empty and should be overloaded. It draws each selectable +object of the scene, enclosed by calls to \c glPushName() / \c glPopName() to +tag the object with an integer id. + +\arg endSelection() then restores \c GL_RENDER mode and analyzes the +selectBuffer() to set in selectedName() the id of the object that was drawn in +the region. If several object are in the region, the closest one in the depth +buffer is chosen. If no object has been drawn under cursor, selectedName() is +set to -1. + +\arg postSelection() is empty and can be overloaded for possible +signal/display/interface update. + +See the \c glSelectBuffer() man page for details on this \c GL_SELECT mechanism. + +This default implementation is quite limited: only the closer object is +selected, and only one level of names can be pushed. However, this reveals +sufficient in many cases and you usually only have to overload drawWithNames() +to implement a simple object selection process. See the select example for an illustration. + +If you need a more complex selection process (such as a point, edge or triangle +selection, which is easier with a 2 or 3 levels selectBuffer() heap, and which +requires a finer depth sorting to privilege point over edge and edges over +triangles), overload the endSelection() method. Use setSelectRegionWidth(), +setSelectRegionHeight() and setSelectBufferSize() to tune the select buffer +configuration. See the multiSelect +example for an illustration. + +\p point is the center pixel (origin in the upper left corner) of the selection +region. Use CGAL::qglviewer::Camera::convertClickToLine() to transform these +coordinates in a 3D ray if you want to perform an analytical intersection. + +\attention \c GL_SELECT mode seems to report wrong results when used in +conjunction with backface culling. If you encounter problems try to \c +glDisable(GL_CULL_FACE). */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::select(const QPoint &point) { + beginSelection(point); + drawWithNames(); + endSelection(point); + postSelection(point); +} + +/*! This method should prepare the selection. It is called by select() before +drawWithNames(). +*/ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::beginSelection(const QPoint &point) +{ + makeCurrent(); + glEnable(GL_SCISSOR_TEST); + glScissor(point.x(), camera()->screenHeight()-1-point.y(), 1, 1); +} + +/*! This method is called by select() after scene elements were drawn by +drawWithNames(). + It clears the OpenGL state set by beginSelection*/ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::endSelection(const QPoint &point) { + Q_UNUSED(point); + glDisable(GL_SCISSOR_TEST); +} + +/*! Sets the selectBufferSize(). + +The previous selectBuffer() is deleted and a new one is created. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setSelectBufferSize(int size) { + if (selectBuffer_) + delete[] selectBuffer_; + selectBufferSize_ = size; + selectBuffer_ = new GLuint[selectBufferSize()]; +} + +static QString mouseButtonsString(::Qt::MouseButtons b) { + QString result(""); + bool addAmpersand = false; + if (b & ::Qt::LeftButton) { + result += CGAL::QGLViewer::tr("Left", "left mouse button"); + addAmpersand = true; + } + if (b & ::Qt::MidButton) { + if (addAmpersand) + result += " & "; + result += CGAL::QGLViewer::tr("Middle", "middle mouse button"); + addAmpersand = true; + } + if (b & ::Qt::RightButton) { + if (addAmpersand) + result += " & "; + result += CGAL::QGLViewer::tr("Right", "right mouse button"); + } + return result; +} + +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::performClickAction(qglviewer::ClickAction ca, const QMouseEvent *const e) { + // Note: action that need it should call update(). + switch (ca) { + // # CONNECTION setMouseBinding prevents adding NO_CLICK_ACTION in + // clickBinding_ This case should hence not be possible. Prevents unused case + // warning. + case qglviewer::NO_CLICK_ACTION: + break; + case qglviewer::ZOOM_ON_PIXEL: + camera()->interpolateToZoomOnPixel(e->pos()); + break; + case qglviewer::ZOOM_TO_FIT: + camera()->interpolateToFitScene(); + break; + case qglviewer::SELECT: + select(e); + update(); + break; + case qglviewer::RAP_FROM_PIXEL: + if (!camera()->setPivotPointFromPixel(e->pos())) + camera()->setPivotPoint(sceneCenter()); + setVisualHintsMask(1); + update(); + break; + case qglviewer::RAP_IS_CENTER: + camera()->setPivotPoint(sceneCenter()); + setVisualHintsMask(1); + update(); + break; + case qglviewer::CENTER_FRAME: + if (manipulatedFrame()) + manipulatedFrame()->projectOnLine(camera()->position(), + camera()->viewDirection()); + break; + case qglviewer::CENTER_SCENE: + camera()->centerScene(); + break; + case qglviewer::SHOW_ENTIRE_SCENE: + camera()->showEntireScene(); + break; + case qglviewer::ALIGN_FRAME: + if (manipulatedFrame()) + manipulatedFrame()->alignWithFrame(camera()->frame()); + break; + case qglviewer::ALIGN_CAMERA: + qglviewer::Frame *frame = new qglviewer::Frame(); + frame->setTranslation(camera()->pivotPoint()); + camera()->frame()->alignWithFrame(frame, true); + delete frame; + break; + } +} + +/*! Overloading of the \c QWidget method. + +When the user clicks on the mouse: +\arg if a mouseGrabber() is defined, CGAL::qglviewer::MouseGrabber::mousePressEvent() +is called, \arg otherwise, the camera() or the manipulatedFrame() interprets the +mouse displacements, depending on mouse bindings. + +Mouse bindings customization can be achieved using setMouseBinding() and +setWheelBinding(). See the mouse page for a complete +description of mouse bindings. + +See the mouseMoveEvent() documentation for an example of more complex mouse +behavior customization using overloading. + +\note When the mouseGrabber() is a manipulatedFrame(), the modifier keys are not +taken into account. This allows for a direct manipulation of the +manipulatedFrame() when the mouse hovers, which is probably what is expected. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::mousePressEvent(QMouseEvent *e) { + //#CONNECTION# mouseDoubleClickEvent has the same structure + //#CONNECTION# mouseString() concatenates bindings description in inverse + // order. + ClickBindingPrivate cbp(e->modifiers(), e->button(), false, + (::Qt::MouseButtons)(e->buttons() & ~(e->button())), + currentlyPressedKey_); + + if (clickBinding_.contains(cbp)) { + performClickAction(clickBinding_[cbp], e); + } else if (mouseGrabber()) { + if (mouseGrabberIsAManipulatedFrame_) { + for (QMap::ConstIterator + it = mouseBinding_.begin(), + end = mouseBinding_.end(); + it != end; ++it) + if ((it.value().handler == qglviewer::FRAME) && (it.key().button == e->button())) { + qglviewer::ManipulatedFrame *mf = + dynamic_cast(mouseGrabber()); + if (mouseGrabberIsAManipulatedCameraFrame_) { + mf->qglviewer::ManipulatedFrame::startAction(it.value().action, + it.value().withConstraint); + mf->qglviewer::ManipulatedFrame::mousePressEvent(e, camera()); + } else { + mf->startAction(it.value().action, it.value().withConstraint); + mf->mousePressEvent(e, camera()); + } + break; + } + } else + mouseGrabber()->mousePressEvent(e, camera()); + update(); + } else { + //#CONNECTION# wheelEvent has the same structure + const MouseBindingPrivate mbp(e->modifiers(), e->button(), + currentlyPressedKey_); + + if (mouseBinding_.contains(mbp)) { + MouseActionPrivate map = mouseBinding_[mbp]; + switch (map.handler) { + case qglviewer::CAMERA: + camera()->frame()->startAction(map.action, map.withConstraint); + camera()->frame()->mousePressEvent(e, camera()); + break; + case qglviewer::FRAME: + if (manipulatedFrame()) { + if (manipulatedFrameIsACamera_) { + manipulatedFrame()->ManipulatedFrame::startAction( + map.action, map.withConstraint); + manipulatedFrame()->ManipulatedFrame::mousePressEvent(e, camera()); + } else { + manipulatedFrame()->startAction(map.action, map.withConstraint); + manipulatedFrame()->mousePressEvent(e, camera()); + } + } + break; + } + if (map.action == qglviewer::SCREEN_ROTATE) + // Display visual hint line + update(); + } else + e->ignore(); + } +} + +/*! Overloading of the \c QWidget method. + +Mouse move event is sent to the mouseGrabber() (if any) or to the camera() or +the manipulatedFrame(), depending on mouse bindings (see setMouseBinding()). + +If you want to define your own mouse behavior, do something like this: +\code +CGAL_INLINE_FUNCTION +void Viewer::mousePressEvent(QMouseEvent* e) +{ + +if ((e->button() == myButton) && (e->modifiers() == myModifiers)) + myMouseBehavior = true; +else + CGAL::QGLViewer::mousePressEvent(e); +} + +CGAL_INLINE_FUNCTION +void Viewer::mouseMoveEvent(QMouseEvent *e) +{ +if (myMouseBehavior) + // Use e->x() and e->y() as you want... +else + CGAL::QGLViewer::mouseMoveEvent(e); +} + +CGAL_INLINE_FUNCTION +void Viewer::mouseReleaseEvent(QMouseEvent* e) +{ +if (myMouseBehavior) + myMouseBehavior = false; +else + CGAL::QGLViewer::mouseReleaseEvent(e); +} +\endcode */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::mouseMoveEvent(QMouseEvent *e) { + if (mouseGrabber()) { + mouseGrabber()->checkIfGrabsMouse(e->x(), e->y(), camera()); + if (mouseGrabber()->grabsMouse()) + if (mouseGrabberIsAManipulatedCameraFrame_) + (dynamic_cast(mouseGrabber())) + ->qglviewer::ManipulatedFrame::mouseMoveEvent(e, camera()); + else + mouseGrabber()->mouseMoveEvent(e, camera()); + else + setMouseGrabber(NULL); + update(); + } + + if (!mouseGrabber()) { + //#CONNECTION# mouseReleaseEvent has the same structure + if (camera()->frame()->isManipulated()) { + camera()->frame()->mouseMoveEvent(e, camera()); + // #CONNECTION# manipulatedCameraFrame::mouseMoveEvent specific if at the + // beginning + if (camera()->frame()->action_ == qglviewer::ZOOM_ON_REGION) + update(); + } else // ! + if ((manipulatedFrame()) && (manipulatedFrame()->isManipulated())) + if (manipulatedFrameIsACamera_) + manipulatedFrame()->ManipulatedFrame::mouseMoveEvent(e, camera()); + else + manipulatedFrame()->mouseMoveEvent(e, camera()); + else if (hasMouseTracking()) { + Q_FOREACH (qglviewer::MouseGrabber *mg, qglviewer::MouseGrabber::MouseGrabberPool()) { + mg->checkIfGrabsMouse(e->x(), e->y(), camera()); + if (mg->grabsMouse()) { + setMouseGrabber(mg); + // Check that MouseGrabber is not disabled + if (mouseGrabber() == mg) { + update(); + break; + } + } + } + } + } +} + +/*! Overloading of the \c QWidget method. + +Calls the mouseGrabber(), camera() or manipulatedFrame \c mouseReleaseEvent +method. + +See the mouseMoveEvent() documentation for an example of mouse behavior +customization. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::mouseReleaseEvent(QMouseEvent *e) { + if (mouseGrabber()) { + if (mouseGrabberIsAManipulatedCameraFrame_) + (dynamic_cast(mouseGrabber())) + ->qglviewer::ManipulatedFrame::mouseReleaseEvent(e, camera()); + else + mouseGrabber()->mouseReleaseEvent(e, camera()); + mouseGrabber()->checkIfGrabsMouse(e->x(), e->y(), camera()); + if (!(mouseGrabber()->grabsMouse())) + setMouseGrabber(NULL); + // update(); + } else + //#CONNECTION# mouseMoveEvent has the same structure + if (camera()->frame()->isManipulated()) { + camera()->frame()->mouseReleaseEvent(e, camera()); + } else if ((manipulatedFrame()) && (manipulatedFrame()->isManipulated())) { + if (manipulatedFrameIsACamera_) + manipulatedFrame()->ManipulatedFrame::mouseReleaseEvent(e, camera()); + else + manipulatedFrame()->mouseReleaseEvent(e, camera()); + } else + e->ignore(); + + // Not absolutely needed (see above commented code for the optimal version), + // but may reveal useful for specific applications. + update(); +} + +/*! Overloading of the \c QWidget method. + +If defined, the wheel event is sent to the mouseGrabber(). It is otherwise sent +according to wheel bindings (see setWheelBinding()). */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::wheelEvent(QWheelEvent *e) { + if (mouseGrabber()) { + if (mouseGrabberIsAManipulatedFrame_) { + for (QMap::ConstIterator + it = wheelBinding_.begin(), + end = wheelBinding_.end(); + it != end; ++it) + if (it.value().handler == qglviewer::FRAME) { + qglviewer::ManipulatedFrame *mf = + dynamic_cast(mouseGrabber()); + if (mouseGrabberIsAManipulatedCameraFrame_) { + mf->qglviewer::ManipulatedFrame::startAction(it.value().action, + it.value().withConstraint); + mf->qglviewer::ManipulatedFrame::wheelEvent(e, camera()); + } else { + mf->startAction(it.value().action, it.value().withConstraint); + mf->wheelEvent(e, camera()); + } + break; + } + } else + mouseGrabber()->wheelEvent(e, camera()); + update(); + } else { + //#CONNECTION# mousePressEvent has the same structure + WheelBindingPrivate wbp(e->modifiers(), currentlyPressedKey_); + + if (wheelBinding_.contains(wbp)) { + MouseActionPrivate map = wheelBinding_[wbp]; + switch (map.handler) { + case qglviewer::CAMERA: + camera()->frame()->startAction(map.action, map.withConstraint); + camera()->frame()->wheelEvent(e, camera()); + break; + case qglviewer::FRAME: + if (manipulatedFrame()) { + if (manipulatedFrameIsACamera_) { + manipulatedFrame()->ManipulatedFrame::startAction( + map.action, map.withConstraint); + manipulatedFrame()->ManipulatedFrame::wheelEvent(e, camera()); + } else { + manipulatedFrame()->startAction(map.action, map.withConstraint); + manipulatedFrame()->wheelEvent(e, camera()); + } + } + break; + } + } else + e->ignore(); + } +} + +/*! Overloading of the \c QWidget method. + +The behavior of the mouse double click depends on the mouse binding. See +setMouseBinding() and the mouse page. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::mouseDoubleClickEvent(QMouseEvent *e) { + //#CONNECTION# mousePressEvent has the same structure + ClickBindingPrivate cbp(e->modifiers(), e->button(), true, + (::Qt::MouseButtons)(e->buttons() & ~(e->button())), + currentlyPressedKey_); + if (clickBinding_.contains(cbp)) + performClickAction(clickBinding_[cbp], e); + else if (mouseGrabber()) + mouseGrabber()->mouseDoubleClickEvent(e, camera()); + else + e->ignore(); +} + +/*! Sets the state of displaysInStereo(). See also toggleStereoDisplay(). + +First checks that the display is able to handle stereovision using +CGAL_INLINE_FUNCTION +QOpenGLWidget::format(). Opens a warning message box in case of failure. Emits +the stereoChanged() signal otherwise. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setStereoDisplay(bool stereo) { + if (format().stereo()) { + stereo_ = stereo; + if (!displaysInStereo()) { + glDrawBuffer(GL_BACK_LEFT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glDrawBuffer(GL_BACK_RIGHT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + + Q_EMIT stereoChanged(stereo_); + + update(); + } else if (stereo) + QMessageBox::warning(this, + tr("Stereo not supported", "Message box window title"), + tr("Stereo is not supported on this display.")); + else + stereo_ = false; +} + +/*! Sets the isFullScreen() state. + +If the CGAL::QGLViewer is embedded in an other QWidget (see +CGAL_INLINE_FUNCTION +QWidget::topLevelWidget()), this widget is displayed in full screen instead. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setFullScreen(bool fullScreen) { + if (fullScreen_ == fullScreen) + return; + + fullScreen_ = fullScreen; + + QWidget *tlw = topLevelWidget(); + + if (isFullScreen()) { + prevPos_ = topLevelWidget()->pos(); + tlw->showFullScreen(); + tlw->move(0, 0); + } else { + tlw->showNormal(); + tlw->move(prevPos_); + } +} + +/*! Directly defines the mouseGrabber(). + +You should not call this method directly as it bypasses the +CGAL::qglviewer::MouseGrabber::checkIfGrabsMouse() test performed by mouseMoveEvent(). + +If the MouseGrabber is disabled (see mouseGrabberIsEnabled()), this method +silently does nothing. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setMouseGrabber(qglviewer::MouseGrabber *mouseGrabber) { + if (!mouseGrabberIsEnabled(mouseGrabber)) + return; + + mouseGrabber_ = mouseGrabber; + + mouseGrabberIsAManipulatedFrame_ = + (dynamic_cast(mouseGrabber) != NULL); + mouseGrabberIsAManipulatedCameraFrame_ = + ((dynamic_cast(mouseGrabber) != NULL) && + (mouseGrabber != camera()->frame())); + Q_EMIT mouseGrabberChanged(mouseGrabber); +} + +/*! Sets the mouseGrabberIsEnabled() state. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setMouseGrabberIsEnabled( + const CGAL::qglviewer::MouseGrabber *const mouseGrabber, bool enabled) { + if (enabled) + disabledMouseGrabbers_.remove(reinterpret_cast(mouseGrabber)); + else + disabledMouseGrabbers_[reinterpret_cast(mouseGrabber)]; +} + +CGAL_INLINE_FUNCTION +QString CGAL::QGLViewer::mouseActionString(qglviewer::MouseAction ma) { + switch (ma) { + case CGAL::qglviewer::NO_MOUSE_ACTION: + return QString::null; + case CGAL::qglviewer::ROTATE: + return CGAL::QGLViewer::tr("Rotates", "ROTATE mouse action"); + case CGAL::qglviewer::ZOOM: + return CGAL::QGLViewer::tr("Zooms", "ZOOM mouse action"); + case CGAL::qglviewer::TRANSLATE: + return CGAL::QGLViewer::tr("Translates", "TRANSLATE mouse action"); + case CGAL::qglviewer::MOVE_FORWARD: + return CGAL::QGLViewer::tr("Moves forward", "MOVE_FORWARD mouse action"); + case CGAL::qglviewer::LOOK_AROUND: + return CGAL::QGLViewer::tr("Looks around", "LOOK_AROUND mouse action"); + case CGAL::qglviewer::MOVE_BACKWARD: + return CGAL::QGLViewer::tr("Moves backward", "MOVE_BACKWARD mouse action"); + case CGAL::qglviewer::SCREEN_ROTATE: + return CGAL::QGLViewer::tr("Rotates in screen plane", + "SCREEN_ROTATE mouse action"); + case CGAL::qglviewer::ROLL: + return CGAL::QGLViewer::tr("Rolls", "ROLL mouse action"); + case CGAL::qglviewer::DRIVE: + return CGAL::QGLViewer::tr("Drives", "DRIVE mouse action"); + case CGAL::qglviewer::SCREEN_TRANSLATE: + return CGAL::QGLViewer::tr("Horizontally/Vertically translates", + "SCREEN_TRANSLATE mouse action"); + case CGAL::qglviewer::ZOOM_ON_REGION: + return CGAL::QGLViewer::tr("Zooms on region for", "ZOOM_ON_REGION mouse action"); + } + return QString::null; +} + +CGAL_INLINE_FUNCTION +QString CGAL::QGLViewer::clickActionString(CGAL::qglviewer::ClickAction ca) { + switch (ca) { + case CGAL::qglviewer::NO_CLICK_ACTION: + return QString::null; + case CGAL::qglviewer::ZOOM_ON_PIXEL: + return CGAL::QGLViewer::tr("Zooms on pixel", "ZOOM_ON_PIXEL click action"); + case CGAL::qglviewer::ZOOM_TO_FIT: + return CGAL::QGLViewer::tr("Zooms to fit scene", "ZOOM_TO_FIT click action"); + case CGAL::qglviewer::SELECT: + return CGAL::QGLViewer::tr("Selects", "SELECT click action"); + case CGAL::qglviewer::RAP_FROM_PIXEL: + return CGAL::QGLViewer::tr("Sets pivot point", "RAP_FROM_PIXEL click action"); + case CGAL::qglviewer::RAP_IS_CENTER: + return CGAL::QGLViewer::tr("Resets pivot point", "RAP_IS_CENTER click action"); + case CGAL::qglviewer::CENTER_FRAME: + return CGAL::QGLViewer::tr("Centers manipulated frame", + "CENTER_FRAME click action"); + case CGAL::qglviewer::CENTER_SCENE: + return CGAL::QGLViewer::tr("Centers scene", "CENTER_SCENE click action"); + case CGAL::qglviewer::SHOW_ENTIRE_SCENE: + return CGAL::QGLViewer::tr("Shows entire scene", + "SHOW_ENTIRE_SCENE click action"); + case CGAL::qglviewer::ALIGN_FRAME: + return CGAL::QGLViewer::tr("Aligns manipulated frame", + "ALIGN_FRAME click action"); + case CGAL::qglviewer::ALIGN_CAMERA: + return CGAL::QGLViewer::tr("Aligns camera", "ALIGN_CAMERA click action"); + } + return QString::null; +} + +static QString keyString(unsigned int key) { +#if QT_VERSION >= 0x040100 + return QKeySequence(int(key)).toString(QKeySequence::NativeText); +#else + return QString(QKeySequence(key)); +#endif +} + +CGAL_INLINE_FUNCTION +QString CGAL::QGLViewer::formatClickActionPrivate(ClickBindingPrivate cbp) { + bool buttonsBefore = cbp.buttonsBefore != ::Qt::NoButton; + QString keyModifierString = keyString(cbp.modifiers + cbp.key); + if (!keyModifierString.isEmpty()) { +#ifdef Q_OS_MAC + // modifiers never has a '+' sign. Add one space to clearly separate + // modifiers (and possible key) from button + keyModifierString += " "; +#else + // modifiers might be of the form : 'S' or 'Ctrl+S' or 'Ctrl+'. For + // consistency, add an other '+' if needed, no spaces + if (!keyModifierString.endsWith('+')) + keyModifierString += "+"; +#endif + } + + return tr("%1%2%3%4%5%6", "Modifier / button or wheel / double click / with " + "/ button / pressed") + .arg(keyModifierString) + .arg(mouseButtonsString(cbp.button) + + (cbp.button == ::Qt::NoButton ? tr("Wheel", "Mouse wheel") : "")) + .arg(cbp.doubleClick ? tr(" double click", "Suffix after mouse button") + : "") + .arg(buttonsBefore ? tr(" with ", "As in : Left button with Ctrl pressed") + : "") + .arg(buttonsBefore ? mouseButtonsString(cbp.buttonsBefore) : "") + .arg(buttonsBefore + ? tr(" pressed", "As in : Left button with Ctrl pressed") + : ""); +} + +CGAL_INLINE_FUNCTION +bool CGAL::QGLViewer::isValidShortcutKey(int key) { + return (key >= ::Qt::Key_Any && key < ::Qt::Key_Escape) || + (key >= ::Qt::Key_F1 && key <= ::Qt::Key_F35); +} + + +/*! Defines a custom mouse binding description, displayed in the help() window's + Mouse tab. + + Same as calling setMouseBindingDescription(::Qt::Key, ::Qt::KeyboardModifiers, + ::Qt::MouseButton, QString, bool, ::Qt::MouseButtons), with a key value of + ::Qt::Key(0) (i.e. binding description when no regular key needs to be pressed). + */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setMouseBindingDescription(::Qt::KeyboardModifiers modifiers, + ::Qt::MouseButton button, + QString description, + bool doubleClick, + ::Qt::MouseButtons buttonsBefore) { + setMouseBindingDescription(::Qt::Key(0), modifiers, button, description, + doubleClick, buttonsBefore); +} + +/*! Defines a custom mouse binding description, displayed in the help() window's +Mouse tab. + +\p modifiers is a combination of ::Qt::KeyboardModifiers (\c ::Qt::ControlModifier, +\c ::Qt::AltModifier, \c ::Qt::ShiftModifier, \c ::Qt::MetaModifier). Possibly +combined using the \c "|" operator. + +\p button is one of the ::Qt::MouseButtons (\c ::Qt::LeftButton, \c ::Qt::MidButton, +\c ::Qt::RightButton...). + +\p doubleClick indicates whether or not the user has to double click this button +to perform the described action. \p buttonsBefore lists the buttons that need to +be pressed before the double click. + +Set an empty \p description to \e remove a mouse binding description. + +\code +// The R key combined with the Left mouse button rotates the camera in the +screen plane. setMouseBindingDescription(::Qt::Key_R, ::Qt::NoModifier, +::Qt::LeftButton, "Rotates camera in screen plane"); + +// A left button double click toggles full screen +setMouseBindingDescription(::Qt::NoModifier, ::Qt::LeftButton, "Toggles full screen +mode", true); + +// Removes the description of Ctrl+Right button +setMouseBindingDescription(::Qt::ControlModifier, ::Qt::RightButton, ""); +\endcode + +Overload mouseMoveEvent() and friends to implement your custom mouse behavior +(see the mouseMoveEvent() documentation for an example). See the keyboardAndMouse example for an +illustration. + +Use setMouseBinding() and setWheelBinding() to change the standard mouse action +bindings. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setMouseBindingDescription( + ::Qt::Key key, ::Qt::KeyboardModifiers modifiers, ::Qt::MouseButton button, + QString description, bool doubleClick, ::Qt::MouseButtons buttonsBefore) { + ClickBindingPrivate cbp(modifiers, button, doubleClick, buttonsBefore, key); + + if (description.isEmpty()) + mouseDescription_.remove(cbp); + else + mouseDescription_[cbp] = description; +} + +static QString tableLine(const QString &left, const QString &right) { + static bool even = false; + const QString tdtd("
\n"); + + QString res(""; + else + res += "#ffffff\">"; + res += " C3t3; + +// Criteria +typedef CGAL::Mesh_criteria_3 Mesh_criteria; + +// To avoid verbose function and named parameters call +using namespace CGAL::parameters; + +template +struct Image_to_multiple_iso_level_sets { + const Set& set; + Image_to_multiple_iso_level_sets(const Set& set) : set(set) {} + + int operator()(double v) const { + return int(std::distance(set.begin(), + set.lower_bound(float(v)))); + } +}; + +int main(int argc, char*argv[]) +{ + const char* fname = (argc>1)?argv[1]:"data/skull_2.9.inr"; + // Load image + CGAL::Image_3 image; + if(!image.read(fname)){ + std::cerr << "Error: Cannot read file " << fname << std::endl; + return EXIT_FAILURE; + } + + typedef boost::container::flat_set Flat_set; + Flat_set iso_values; + if(argc < 3) { + iso_values.insert(2.9f); + } else { + for(int i = 2; i < argc; ++i) { + iso_values.insert(static_cast(std::atof(argv[i]))); + } + } + + // Domain + namespace p = CGAL::parameters; + Mesh_domain domain = + Mesh_domain::create_gray_image_mesh_domain + (p::image = image, + p::image_values_to_subdomain_indices = + Image_to_multiple_iso_level_sets(iso_values), + p::value_outside = 0.f + ); + + // Mesh criteria + Mesh_criteria criteria(facet_angle=30, facet_size=6, facet_distance=2, + cell_radius_edge_ratio=3, cell_size=8); + + // Meshing + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria); + + // Output + std::ofstream medit_file("out.mesh"); + c3t3.output_to_medit(medit_file); + + return 0; +} diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_gray_vtk_image.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_gray_vtk_image.cpp index 55c6487817f..45c6124cce0 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_gray_vtk_image.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_gray_vtk_image.cpp @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include #include @@ -23,9 +23,7 @@ typedef short Image_word_type; // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Gray_image_mesh_domain_3 > > Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; // Triangulation typedef CGAL::Mesh_triangulation_3::type Tr; @@ -34,8 +32,16 @@ typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; // Criteria typedef CGAL::Mesh_criteria_3 Mesh_criteria; -// To avoid verbose function and named parameters call -using namespace CGAL::parameters; +class Less { + double iso; +public: + Less(double iso): iso(iso) {} + + template + int operator()(T v) const { + return int(v < iso); + } +}; int main(int argc, char* argv[]) { @@ -72,9 +78,16 @@ int main(int argc, char* argv[]) std::cerr << "could not create a CGAL::Image_3 from the vtk image\n"; return 0; } - // Domain - Mesh_domain domain(image, boost::bind1st(std::less(), iso), 0); - + /// [Domain creation] + // To avoid verbose function and named parameters call + using namespace CGAL::parameters; + + Mesh_domain domain = Mesh_domain::create_gray_image_mesh_domain + (image, + image_values_to_subdomain_indices = Less(iso), + value_outside = 0); + /// [Domain creation] + // Mesh criteria Mesh_criteria criteria(facet_angle=30, facet_size=fs, facet_distance=fd, cell_radius_edge_ratio=3, cell_size=cs); diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image.cpp index 8fa9d544102..c7dad626119 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image.cpp @@ -4,13 +4,13 @@ #include #include -#include +#include #include #include // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Labeled_image_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; #ifdef CGAL_CONCURRENT_MESH_3 typedef CGAL::Parallel_tag Concurrency_tag; @@ -40,8 +40,9 @@ int main(int argc, char* argv[]) } /// [Loads image] - // Domain - Mesh_domain domain(image); + /// [Domain creation] + Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image); + /// [Domain creation] // Mesh criteria Mesh_criteria criteria(facet_angle=30, facet_size=6, facet_distance=4, diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_variable_size.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_variable_size.cpp index b5b975ee879..be26a22b3a5 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_variable_size.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_variable_size.cpp @@ -7,13 +7,13 @@ #include #include -#include +#include #include #include // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Labeled_image_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; #ifdef CGAL_CONCURRENT_MESH_3 typedef CGAL::Parallel_tag Concurrency_tag; @@ -45,7 +45,7 @@ int main(int argc, char* argv[]) } // Domain - Mesh_domain domain(image); + Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image); // Sizing field: set global size to 8 and kidney size (label 127) to 3 double kidney_size = 3.; diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp index 9197c4239bf..9bd06e32ae4 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_custom_initialization.cpp @@ -7,7 +7,7 @@ #include -#include +#include #include #include @@ -15,7 +15,7 @@ // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Labeled_image_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; #ifdef CGAL_CONCURRENT_MESH_3 typedef CGAL::Parallel_tag Concurrency_tag; @@ -41,7 +41,7 @@ int main() /// [Create the image] // Domain - Mesh_domain domain(image); + Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image); // Mesh criteria Mesh_criteria criteria(facet_angle=30, facet_size=3, facet_distance=1, diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_features.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_features.cpp index 4292d2a257a..e2334150529 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_image_with_features.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_image_with_features.cpp @@ -11,10 +11,10 @@ /// [Domain definition] #include #include -#include +#include typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Labeled_image_mesh_domain_3 Image_domain; +typedef CGAL::Labeled_mesh_domain_3 Image_domain; typedef CGAL::Mesh_domain_with_polyline_features_3 Mesh_domain; /// [Domain definition] @@ -47,7 +47,7 @@ bool add_1D_features(const CGAL::Image_3& image, const char* lines_fname) { typedef K::Point_3 Point_3; - typedef Mesh_domain::Image_word_type Word_type; // that is `unsigned char` + typedef unsigned char Word_type; std::vector > features_inside; if(!read_polylines(lines_fname, features_inside)) // see file "read_polylines.h" @@ -81,7 +81,7 @@ int main(int argc, char* argv[]) } // Domain - Mesh_domain domain(image); + Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image); /// Declare 1D-features, see above [Call add_1D_features] const char* lines_fname = (argc>2)?argv[2]:"data/420.polylines.txt"; diff --git a/Mesh_3/examples/Mesh_3/mesh_cubes_intersection.cpp b/Mesh_3/examples/Mesh_3/mesh_cubes_intersection.cpp index 3b9da29830e..f0d8e94348e 100644 --- a/Mesh_3/examples/Mesh_3/mesh_cubes_intersection.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_cubes_intersection.cpp @@ -29,7 +29,7 @@ typedef FT (*Function)(const Point&); typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper Function_wrapper; typedef Function_wrapper::Function_vector Function_vector; -typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; // Triangulation typedef CGAL::Mesh_triangulation_3::type Tr; diff --git a/Mesh_3/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp b/Mesh_3/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp index 0ab5d0d7ffc..60bd95f7815 100644 --- a/Mesh_3/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_cubes_intersection_with_features.cpp @@ -30,7 +30,7 @@ typedef FT (*Function)(const Point&); typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper Function_wrapper; typedef Function_wrapper::Function_vector Function_vector; -typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; typedef CGAL::Mesh_domain_with_polyline_features_3 Mesh_domain_with_features; // Triangulation diff --git a/Mesh_3/examples/Mesh_3/mesh_hybrid_mesh_domain.cpp b/Mesh_3/examples/Mesh_3/mesh_hybrid_mesh_domain.cpp index 9c5a5d1ae50..eb6cec632ac 100644 --- a/Mesh_3/examples/Mesh_3/mesh_hybrid_mesh_domain.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_hybrid_mesh_domain.cpp @@ -6,14 +6,12 @@ #include #include -#include +#include +#include #include #include #include -// IO -#include - // Ouput #include @@ -22,10 +20,8 @@ // Sphere Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef K::FT FT; -typedef K::Point_3 Point; -typedef FT (Function)(const Point&); -typedef CGAL::Implicit_mesh_domain_3 Implicit_domain; + +typedef CGAL::Labeled_mesh_domain_3 Implicit_domain; // Polyhedral Domain typedef CGAL::Polyhedron_3 Polyhedron; @@ -182,6 +178,9 @@ typedef Mesh_criteria::Facet_criteria Facet_criteria; typedef Mesh_criteria::Cell_criteria Cell_criteria; // Function +typedef K::FT FT; +typedef K::Point_3 Point; + FT sphere_centered_at_111 (const Point& p) { const FT dx=p.x()-1; @@ -214,8 +213,10 @@ int main() // - the first argument is the function pointer // - the second argument is a bounding sphere of the domain // (Warning: Sphere_3 constructor uses square radius !) - Implicit_domain sphere_domain(sphere_centered_at_111, - K::Sphere_3(K::Point_3(1, 1, 1), 2.)); + Implicit_domain sphere_domain = + Implicit_domain::create_implicit_mesh_domain(sphere_centered_at_111, + K::Sphere_3(K::Point_3(1, 1, 1), + 2.)); Domain domain(sphere_domain, polyhedron_domain); diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_domains.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_domains.cpp index 073fb09082e..ba9c950f610 100644 --- a/Mesh_3/examples/Mesh_3/mesh_implicit_domains.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_implicit_domains.cpp @@ -20,7 +20,7 @@ typedef FT_to_point_function_wrapper Function; typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper Function_wrapper; typedef Function_wrapper::Function_vector Function_vector; -typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; // Triangulation typedef CGAL::Mesh_triangulation_3::type Tr; @@ -43,7 +43,7 @@ int main() v.push_back(f2); // Domain (Warning: Sphere_3 constructor uses square radius !) - Mesh_domain domain(v, K::Sphere_3(CGAL::ORIGIN, 5.*5.), 1e-6); + Mesh_domain domain(Function_wrapper(v), K::Sphere_3(CGAL::ORIGIN, 5.*5.), 1e-6); // Set mesh criteria Facet_criteria facet_criteria(30, 0.2, 0.02); // angle, size, approximation diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp index 41daf9fd6dd..1db89900160 100644 --- a/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_implicit_domains_2.cpp @@ -20,7 +20,7 @@ typedef FT_to_point_function_wrapper Function; typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper Function_wrapper; typedef Function_wrapper::Function_vector Function_vector; -typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; // Triangulation typedef CGAL::Mesh_triangulation_3::type Tr; @@ -45,8 +45,13 @@ int main() std::vector vps; vps.push_back("+-"); - // Domain (Warning: Sphere_3 constructor uses square radius !) - Mesh_domain domain(Function_wrapper(v, vps), K::Sphere_3(CGAL::ORIGIN, 5.*5.)); + /// [Domain creation] (Warning: Sphere_3 constructor uses square radius !) + namespace param = CGAL::parameters; + Mesh_domain domain(param::function = Function_wrapper(v, vps), + param::bounding_object = K::Sphere_3(CGAL::ORIGIN, + 5.*5.), + param::relative_error_bound = 1e-6); + /// [Domain creation] // Set mesh criteria Facet_criteria facet_criteria(30, 0.2, 0.02); // angle, size, approximation diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_ellipsoid.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_ellipsoid.cpp index dbc162aa2c4..f4beb65d75b 100644 --- a/Mesh_3/examples/Mesh_3/mesh_implicit_ellipsoid.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_implicit_ellipsoid.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include #include @@ -14,7 +14,7 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef K::FT FT; typedef K::Point_3 Point; typedef FT (Function)(const Point&); -typedef CGAL::Implicit_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; // Triangulation typedef CGAL::Mesh_triangulation_3::type Tr; @@ -41,7 +41,9 @@ using namespace CGAL::parameters; int main() { // Domain (Warning: Sphere_3 constructor uses square radius !) - Mesh_domain domain(ellipsoid_function, K::Sphere_3(CGAL::ORIGIN, 2.)); + Mesh_domain domain = + Mesh_domain::create_implicit_mesh_domain(ellipsoid_function, + K::Sphere_3(CGAL::ORIGIN, 2.)); // Criteria Facet_criteria facet_criteria(30, 0.08, 0.025); // angle, size, approximation diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_sphere.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_sphere.cpp index 8e3f1234f2f..be66887e6c1 100644 --- a/Mesh_3/examples/Mesh_3/mesh_implicit_sphere.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_implicit_sphere.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include // Domain @@ -12,7 +12,7 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef K::FT FT; typedef K::Point_3 Point; typedef FT (Function)(const Point&); -typedef CGAL::Implicit_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; #ifdef CGAL_CONCURRENT_MESH_3 typedef CGAL::Parallel_tag Concurrency_tag; @@ -37,9 +37,11 @@ FT sphere_function (const Point& p) int main() { - // Domain (Warning: Sphere_3 constructor uses squared radius !) - Mesh_domain domain(sphere_function, - K::Sphere_3(CGAL::ORIGIN, 2.)); + /// [Domain creation] (Warning: Sphere_3 constructor uses squared radius !) + Mesh_domain domain = + Mesh_domain::create_implicit_mesh_domain(sphere_function, + K::Sphere_3(CGAL::ORIGIN, 2.)); + /// [Domain creation] // Mesh criteria Mesh_criteria criteria(facet_angle=30, facet_size=0.1, facet_distance=0.025, diff --git a/Mesh_3/examples/Mesh_3/mesh_implicit_sphere_variable_size.cpp b/Mesh_3/examples/Mesh_3/mesh_implicit_sphere_variable_size.cpp index 42547d8b07b..ef1dd3ef01d 100644 --- a/Mesh_3/examples/Mesh_3/mesh_implicit_sphere_variable_size.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_implicit_sphere_variable_size.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include // Domain @@ -12,7 +12,7 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef K::FT FT; typedef K::Point_3 Point; typedef FT (Function)(const Point&); -typedef CGAL::Implicit_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; #ifdef CGAL_CONCURRENT_MESH_3 typedef CGAL::Parallel_tag Concurrency_tag; @@ -51,9 +51,13 @@ FT sphere_function (const Point& p) int main() { - // Domain (Warning: Sphere_3 constructor uses squared radius !) - Mesh_domain domain(sphere_function, - K::Sphere_3(CGAL::ORIGIN, 2.)); + /// [Domain creation] (Warning: Sphere_3 constructor uses squared radius !) + namespace p = CGAL::parameters; + Mesh_domain domain = Mesh_domain::create_implicit_mesh_domain + (p::function = &sphere_function, + p::bounding_object = K::Sphere_3(CGAL::ORIGIN, 2.) + ); + /// [Domain creation] // Mesh criteria Spherical_sizing_field size; diff --git a/Mesh_3/examples/Mesh_3/mesh_optimization_example.cpp b/Mesh_3/examples/Mesh_3/mesh_optimization_example.cpp index ad6a215093a..b7239352384 100644 --- a/Mesh_3/examples/Mesh_3/mesh_optimization_example.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_optimization_example.cpp @@ -4,13 +4,13 @@ #include #include -#include +#include #include #include // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Labeled_image_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; #ifdef CGAL_CONCURRENT_MESH_3 typedef CGAL::Parallel_tag Concurrency_tag; @@ -39,7 +39,7 @@ int main(int argc, char* argv[]) return EXIT_FAILURE; } - Mesh_domain domain(image); + Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image); // Mesh criteria Mesh_criteria criteria(facet_angle=30, facet_size=5, facet_distance=1.5, diff --git a/Mesh_3/examples/Mesh_3/mesh_optimization_lloyd_example.cpp b/Mesh_3/examples/Mesh_3/mesh_optimization_lloyd_example.cpp index 2f00593c4eb..e79eb4e9c90 100644 --- a/Mesh_3/examples/Mesh_3/mesh_optimization_lloyd_example.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_optimization_lloyd_example.cpp @@ -4,13 +4,13 @@ #include #include -#include +#include #include #include // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Labeled_image_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; #ifdef CGAL_CONCURRENT_MESH_3 typedef CGAL::Parallel_tag Concurrency_tag; @@ -38,7 +38,7 @@ int main(int argc, char*argv[]) std::cerr << "Error: Cannot read file " << fname << std::endl; return EXIT_FAILURE; } - Mesh_domain domain(image); + Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image); // Mesh criteria Mesh_criteria criteria(facet_angle=30, facet_distance=1.2, diff --git a/Mesh_3/examples/Mesh_3/mesh_polyhedral_complex_sm.cpp b/Mesh_3/examples/Mesh_3/mesh_polyhedral_complex_sm.cpp index e617f1b3cdb..4f332bfc990 100644 --- a/Mesh_3/examples/Mesh_3/mesh_polyhedral_complex_sm.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_polyhedral_complex_sm.cpp @@ -27,7 +27,7 @@ typedef CGAL::Sequential_tag Concurrency_tag; typedef CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3< - Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_segment_index> C3t3; + Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_index> C3t3; // Criteria typedef CGAL::Mesh_criteria_3 Mesh_criteria; diff --git a/Mesh_3/examples/Mesh_3/mesh_two_implicit_spheres_with_balls.cpp b/Mesh_3/examples/Mesh_3/mesh_two_implicit_spheres_with_balls.cpp index efab3c774bf..c40e737b389 100644 --- a/Mesh_3/examples/Mesh_3/mesh_two_implicit_spheres_with_balls.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_two_implicit_spheres_with_balls.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include @@ -16,7 +16,7 @@ typedef K::FT FT; typedef K::Point_3 Point; typedef FT (Function)(const Point&); typedef CGAL::Mesh_domain_with_polyline_features_3< - CGAL::Implicit_mesh_domain_3 > Mesh_domain; + CGAL::Labeled_mesh_domain_3 > Mesh_domain; // Polyline typedef std::vector Polyline_3; @@ -60,8 +60,9 @@ FT sphere_function (const Point& p) int main() { // Domain (Warning: Sphere_3 constructor uses squared radius !) - Mesh_domain domain(sphere_function, - K::Sphere_3(Point(1, 0, 0), 6.)); + Mesh_domain domain = + Mesh_domain::create_implicit_mesh_domain(sphere_function, + K::Sphere_3(Point(1, 0, 0), 6.)); // Mesh criteria Mesh_criteria criteria(edge_size = 0.15, diff --git a/Mesh_3/include/CGAL/Gray_image_mesh_domain_3.h b/Mesh_3/include/CGAL/Gray_image_mesh_domain_3.h index 7a2f33e94b4..79da0114811 100644 --- a/Mesh_3/include/CGAL/Gray_image_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Gray_image_mesh_domain_3.h @@ -31,25 +31,10 @@ #include #include #include - -#include +#include namespace CGAL { -namespace internal { - - template - struct Greater_than { - typedef T argument_type; - Greater_than(const T& second) : second(second) {} - bool operator()(const T& first) const { - return std::greater()(first, second); - } - T second; - }; - -} - /** * @class Gray_image_mesh_domain_3 * @@ -57,26 +42,25 @@ namespace internal { */ template, + typename Image_word_type_ = float, + typename Transform = internal::Mesh_3::Greater_than, typename Subdomain_index = int> -class Gray_image_mesh_domain_3 - : public Labeled_mesh_domain_3< - Mesh_3::Image_to_labeled_function_wrapper , - BGT> +class +CGAL_DEPRECATED_MSG +( "The class template `CGAL::Gray_image_mesh_domain_3` is now deprecated. " + "Use the static member function template " + "`Labeled_mesh_domain_3::create_gray_image_mesh_domain` instead.") +Gray_image_mesh_domain_3 + : public Labeled_mesh_domain_3 { public: - typedef Mesh_3::Image_to_labeled_function_wrapper Wrapper; - typedef Labeled_mesh_domain_3 Base; + typedef Labeled_mesh_domain_3 Base; typedef typename Base::Sphere_3 Sphere_3; typedef typename Base::FT FT; @@ -92,9 +76,8 @@ public: : Base(Wrapper(image, Transform(iso_value), Transform(iso_value)(value_outside)), - compute_bounding_box(image), + internal::Mesh_3::compute_bounding_box(image), error_bound, - Null_subdomain_index(), p_rng) { CGAL_assertion(Transform(iso_value)(value_outside) == 0); @@ -106,9 +89,8 @@ public: const FT& error_bound = FT(1e-3), CGAL::Random* p_rng = NULL) : Base(Wrapper(image, transform, transform(value_outside)), - compute_bounding_box(image), + internal::Mesh_3::compute_bounding_box(image), error_bound, - Null_subdomain_index(), p_rng) { CGAL_assertion(transform(value_outside) == 0); @@ -116,30 +98,11 @@ public: /// Destructor virtual ~Gray_image_mesh_domain_3() {} - - -private: - /// Returns a box enclosing image \c im - Bbox_3 compute_bounding_box(const Image& im) const - { - return Bbox_3(-1,-1,-1, - double(im.xdim())*im.vx()+1, - double(im.ydim())*im.vy()+1, - double(im.zdim())*im.vz()+1); - } - -private: - // Disabled copy constructor & assignment operator - typedef Gray_image_mesh_domain_3 Self; - Gray_image_mesh_domain_3(const Self& src); - Self& operator=(const Self& src); - }; // end class Gray_image_mesh_domain_3 - - } // end namespace CGAL #include + #endif // CGAL_GRAY_IMAGE_MESH_DOMAIN_3_H diff --git a/Mesh_3/include/CGAL/Implicit_mesh_domain_3.h b/Mesh_3/include/CGAL/Implicit_mesh_domain_3.h index a690ed5ee7b..3e2a43f3831 100644 --- a/Mesh_3/include/CGAL/Implicit_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Implicit_mesh_domain_3.h @@ -44,15 +44,20 @@ namespace CGAL { * Implements mesh_traits for a domain defined as the negative values of * an implicit function. */ -template > -class Implicit_mesh_domain_3 - : public Labeled_mesh_domain_3 + class Wrapper = Implicit_to_labeling_function_wrapper > +class +CGAL_DEPRECATED_MSG +( "The class template `CGAL::Implicit_mesh_domain_3` is now deprecated. " + "Use the static member function template " + "`Labeled_mesh_domain_3::create_implicit_image_mesh_domain` instead.") +Implicit_mesh_domain_3 + : public Labeled_mesh_domain_3 { public: /// Base type - typedef Labeled_mesh_domain_3 Base; + typedef Labeled_mesh_domain_3 Base; /// Public types typedef typename Base::Sphere_3 Sphere_3; @@ -65,7 +70,7 @@ public: * @param bounding_sphere a bounding sphere of the domain * @param error_bound the error bound relative to the sphere radius */ - Implicit_mesh_domain_3(const Function& f, + Implicit_mesh_domain_3(const Function_& f, const Sphere_3& bounding_sphere, const FT& error_bound = FT(1e-6), CGAL::Random* p_rng = NULL) @@ -78,7 +83,7 @@ public: using Base::bbox; private: // Disabled copy constructor & assignment operator - typedef Implicit_mesh_domain_3 Self; + typedef Implicit_mesh_domain_3 Self; Implicit_mesh_domain_3(const Self& src); Self& operator=(const Self& src); diff --git a/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h b/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h index 2d97a2acde1..5bfa882bcff 100644 --- a/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h +++ b/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h @@ -43,6 +43,8 @@ #include #include #include +#include +#include #include #include @@ -66,26 +68,31 @@ public: /// Constructor Implicit_to_labeling_function_wrapper(const Function_& f) - : r_f_(f) {} + : f_(f) {} - // Default copy constructor and assignment operator are ok - - /// Destructor - ~Implicit_to_labeling_function_wrapper() {} + // Default copy constructor, assignment operator, and destructor are ok /// Operator () - return_type operator()(const Point_3& p, const bool = true) const + return_type operator()(const Point_3& p) const { - return ( (r_f_(p)<0) ? 1 : 0 ); + return ( (f_(p)<0) ? 1 : 0 ); } private: + typedef typename boost::mpl::if_, + Function_*, + Function_>::type Stored_function; /// Function to wrap - const Function_& r_f_; + Stored_function f_; }; // end class Implicit_to_labeling_function_wrapper - +template +Implicit_to_labeling_function_wrapper +make_implicit_to_labeling_function_wrapper(const Function& f) +{ + return Implicit_to_labeling_function_wrapper(f); +} /** * \deprecated @@ -111,7 +118,13 @@ public: /// Constructor Implicit_vector_to_labeling_function_wrapper(const std::vector& v) - : function_vector_(v) {} + : function_vector_(v) + { + if ( v.size() > 8 ) + { + CGAL_error_msg("We support at most 8 functions !"); + } + } // Default copy constructor and assignment operator are ok @@ -119,20 +132,15 @@ public: ~Implicit_vector_to_labeling_function_wrapper() {} /// Operator () - return_type operator()(const Point_3& p, const bool = true) const + return_type operator()(const Point_3& p) const { - int nb_func = function_vector_.size(); - if ( nb_func > 8 ) - { - CGAL_error_msg("We support at most 8 functions !"); - } - + const int nb_func = static_cast(function_vector_.size()); char bits = 0; for ( int i = 0 ; i < nb_func ; ++i ) { // Insert value into bits : we compute fi(p) and insert result at // bit i of bits - bits |= ( ((*function_vector_[i])(p) < 0) << i ); + bits = char(bits | ( ((*function_vector_[i])(p) < 0) << i )); } return ( static_cast(bits) ); @@ -191,7 +199,7 @@ public: typename Bmask::size_type bit_index = 0; for (std::vector::const_iterator iter = mask.begin(), endIter = mask.end(); iter != endIter; ++iter) { - std::string::value_type character = static_cast(*iter); + Sign character = *iter; CGAL_assertion(character == POSITIVE || character == NEGATIVE); bmask[bit_index] = (character == POSITIVE); @@ -258,7 +266,7 @@ public: std::sort(bmasks.begin(), bmasks.end()); } - return_type operator() (const Point_3& p, const bool = true) const + return_type operator() (const Point_3& p) const { Bmask bmask(funcs.size() * 2, false); diff --git a/Mesh_3/include/CGAL/Labeled_image_mesh_domain_3.h b/Mesh_3/include/CGAL/Labeled_image_mesh_domain_3.h index e1d75276105..275a4b312d8 100644 --- a/Mesh_3/include/CGAL/Labeled_image_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Labeled_image_mesh_domain_3.h @@ -51,30 +51,26 @@ template -class Labeled_image_mesh_domain_3 -: public Labeled_mesh_domain_3 - - >::type, - BGT, - Null_subdomain_index - > +class +CGAL_DEPRECATED_MSG +( "The class template `CGAL::Labeled_image_mesh_domain_3` is now deprecated. " + "Use the static member function template " + "`Labeled_mesh_domain_3::create_labeled_image_mesh_domain` instead.") +Labeled_image_mesh_domain_3 + : public Labeled_mesh_domain_3 { public: typedef Image_word_type_ Image_word_type; typedef typename Default::Get >::type Wrapper; typedef typename Default::Get::type Null; - typedef Labeled_mesh_domain_3 Base; + typedef Labeled_mesh_domain_3 Base; typedef typename Base::Sphere_3 Sphere_3; typedef typename Base::FT FT; @@ -91,21 +87,8 @@ public: : Base(Wrapper(image, Identity(), value_outside), compute_bounding_box(image), error_bound, - null, - p_rng) - {} - - Labeled_image_mesh_domain_3(const Image& image, - const CGAL::Bbox_3& bbox, - const FT& error_bound = FT(1e-3), - Subdomain_index value_outside = 0, - Null null = Null(), - CGAL::Random* p_rng = NULL) - : Base(Wrapper(image, Identity(), value_outside), - bbox, - error_bound, - null, - p_rng) + parameters::null_subdomain_index = null, + parameters::p_rng = p_rng) {} Labeled_image_mesh_domain_3(const Image& image, @@ -114,18 +97,6 @@ public: : Base(Wrapper(image), compute_bounding_box(image), error_bound, - Null(), - p_rng) - {} - - Labeled_image_mesh_domain_3(const Image& image, - const CGAL::Bbox_3& bbox, - const FT error_bound, - CGAL::Random* p_rng) - : Base(Wrapper(image), - bbox, - error_bound, - Null(), p_rng) {} @@ -145,13 +116,6 @@ private: double(im.ydim()+1)*im.vy(), double(im.zdim()+1)*im.vz()); } - -private: - // Disabled copy constructor & assignment operator - typedef Labeled_image_mesh_domain_3 Self; - Labeled_image_mesh_domain_3(const Self& src); - Self& operator=(const Self& src); - }; // end class Labeled_image_mesh_domain_3 diff --git a/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h b/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h index 103bf98007a..f015060e4fb 100644 --- a/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Labeled_mesh_domain_3.h @@ -37,23 +37,218 @@ #include -#include -#include +#include +#include +#include +#ifdef CGAL_MESH_3_VERBOSE +# include +#endif #include +#include #include #include -#include +#include +#include #include +#include + +// support for `CGAL::Image_3` +#include +#include + +// support for implicit functions +#include + namespace CGAL { +namespace internal { + +namespace Mesh_3 { + + struct Identity { + template + const T& operator()(const T& x) { return x; } + }; + + template + struct Greater_than { + typedef T argument_type; + typedef bool result_type; + Greater_than(const T& second) : second(second) {} + bool operator()(const T& first) const { + return std::greater()(first, second); + } + T second; + }; + + struct Do_not_delete { + template void operator()(T*) const { } + }; + + /// Returns a box enclosing image \c im + inline Bbox_3 compute_bounding_box(const Image_3& im) + { + return Bbox_3(-1,-1,-1, + double(im.xdim())*im.vx()+1, + double(im.ydim())*im.vy()+1, + double(im.zdim())*im.vz()+1); + } + + template + struct Create_gray_image_values_to_subdomain_indices { + typedef Image_values_to_subdom_indices type; + template + type operator()(Image_values_to_subdom_indices functor, const FT&) const { + return functor; + } + }; + + // specialization for `Null_functor`: create the default functor + template <> + struct Create_gray_image_values_to_subdomain_indices { + typedef internal::Mesh_3::Greater_than type; + template + type operator()(Null_functor, const FT& iso_value) const { + return type(iso_value); + } + }; + + template + struct Create_labeled_image_values_to_subdomain_indices { + typedef Image_values_to_subdom_indices type; + type operator()(Image_values_to_subdom_indices functor) const { + return functor; + } + }; + + // specialization for `Null_functor`: create the default functor + template <> + struct Create_labeled_image_values_to_subdomain_indices { + typedef Identity type; + type operator()(Null_functor) const { + return type(); + } + }; + +} // end namespace CGAL::internal::Mesh_3 +} // end namespace CGAL::internal + struct Null_subdomain_index { template bool operator()(const T& x) const { return 0 == x; } }; +template +struct Construct_pair_from_subdomain_indices { + typedef std::pair result_type; + + result_type operator()(Subdomain_index a, Subdomain_index b) const { + return result_type(a, b); + } +}; // end class template Construct_pair_from_subdomain_indices + +template +class Labeled_mesh_domain_3_impl_details { +protected: + typedef Surface_patch_index_ Surface_patch_index; + typedef typename Geom_traits::Point_3 Point_3; + typedef typename Geom_traits::Sphere_3 Sphere_3; + typedef typename Geom_traits::Iso_cuboid_3 Iso_cuboid_3; + typedef typename Geom_traits::FT FT; + typedef boost::shared_ptr CGAL_Random_share_ptr_t; + /// Returns squared error bound from \c bbox and \c error + FT squared_error_bound(const Iso_cuboid_3& bbox, const FT& error) const + { + typename Geom_traits::Compute_squared_distance_3 squared_distance = + Geom_traits().compute_squared_distance_3_object(); + return squared_distance((bbox.min)(), (bbox.max)())*error*error/4; + } + + static Iso_cuboid_3 iso_cuboid(const Bbox_3& bbox) + { + const Point_3 p_min(bbox.xmin(), bbox.ymin(), bbox.zmin()); + const Point_3 p_max(bbox.xmax(), bbox.ymax(), bbox.zmax()); + + return Iso_cuboid_3(p_min,p_max); + } + + static Iso_cuboid_3 iso_cuboid(const typename Geom_traits::Sphere_3& sphere) + { + return iso_cuboid(sphere.bbox()); + } + + static Iso_cuboid_3 iso_cuboid(const typename Geom_traits::Iso_cuboid_3& c) + { + return c; + } + + static Construct_pair_from_subdomain_indices + construct_pair_functor() { + return Construct_pair_from_subdomain_indices(); + } + + template + Labeled_mesh_domain_3_impl_details(ArgumentPack const& args) + : function_(args[parameters::function]) + , bbox_(iso_cuboid(args[parameters::bounding_object])) + , cstr_s_p_index(args[parameters::construct_surface_patch_index | + construct_pair_functor()]) + , null(args[parameters::null_subdomain_index | Null_subdomain_index()]) + , p_rng_(args[parameters::p_rng|0] == 0 ? + CGAL_Random_share_ptr_t(new CGAL::Random(0)) : + CGAL_Random_share_ptr_t(args[parameters::p_rng|(CGAL::Random*)(0)], + internal::Mesh_3::Do_not_delete())) + , squared_error_bound_ + ( squared_error_bound(bbox_, + args[parameters::relative_error_bound|FT(1e-3)])) + { + } + + template + Labeled_mesh_domain_3_impl_details(const Function& f, + const Bounding_object& bounding, + const FT& error_bound, + Construct_surface_patch_index cstr_s_p_i, + Null null, + CGAL::Random* p_rng) + : function_(f) + , bbox_(iso_cuboid(bounding)) + , cstr_s_p_index(cstr_s_p_i) + , null(null) + , p_rng_(p_rng == 0 ? + CGAL_Random_share_ptr_t(new CGAL::Random(0)) : + CGAL_Random_share_ptr_t(p_rng, internal::Mesh_3::Do_not_delete())) + , squared_error_bound_(squared_error_bound(bbox_,error_bound)) + {} + + /// The function which answers subdomain queries + typedef CGAL::cpp11::function Function; + Function function_; + /// The bounding box + const Iso_cuboid_3 bbox_; + + typedef CGAL::cpp11::function< + Surface_patch_index(Subdomain_index, + Subdomain_index)> Construct_surface_patch_index; + Construct_surface_patch_index cstr_s_p_index; + /// The functor that decides which sub-domain indices correspond to the + /// outside of the domain. + typedef CGAL::cpp11::function Null; + Null null; + /// The random number generator used by Construct_initial_points + CGAL_Random_share_ptr_t p_rng_; + /// Error bound relative to sphere radius + FT squared_error_bound_; +}; // Labeled_mesh_domain_3_impl_details + /** * \class Labeled_mesh_domain_3 * @@ -66,12 +261,42 @@ struct Null_subdomain_index { * tags of it's incident subdomain. * Thus, a boundary facet of the domain is labelled <0,b>, where b!=0. */ -template -class Labeled_mesh_domain_3 +template > +class Labeled_mesh_domain_3 : + protected Labeled_mesh_domain_3_impl_details { - typedef typename Default::Get::type Null; +public: + //------------------------------------------------------- + // Index Types + //------------------------------------------------------- + /// Type of indexes for cells of the input complex + typedef Subdomain_index_ Subdomain_index; + typedef boost::optional Subdomain; + + /// Type of indexes for cells of the input complex + typedef Surface_patch_index_ Surface_patch_index; + typedef boost::optional Surface_patch; + + /// Type of indexes to characterize the lowest dimensional face of the input + /// complex on which a vertex lie + typedef typename CGAL::internal::Mesh_3:: + Index_generator::Index Index; + +private: + typedef Labeled_mesh_domain_3_impl_details Impl_details; + typedef typename Impl_details::Null Null; + typedef typename Impl_details::Construct_surface_patch_index + Construct_surface_patch_index; + typedef typename Impl_details::Function Function; + public: /// Geometric object types typedef typename BGT::Point_3 Point_3; @@ -91,66 +316,178 @@ public: // access Function type from inherited class typedef Function Fct; - //------------------------------------------------------- - // Index Types - //------------------------------------------------------- - /// Type of indexes for cells of the input complex - typedef typename Function::return_type Subdomain_index; - typedef boost::optional Subdomain; - /// Type of indexes for surface patch of the input complex - typedef std::pair Surface_patch_index; - typedef boost::optional Surface_patch; - /// Type of indexes to characterize the lowest dimensional face of the input - /// complex on which a vertex lie - typedef boost::variant Index; typedef CGAL::cpp11::tuple Intersection; typedef typename BGT::FT FT; typedef BGT Geom_traits; + + BOOST_PARAMETER_CONSTRUCTOR(Labeled_mesh_domain_3, + (Impl_details), + parameters::tag, + (required + (function_,(Function)) + (bounding_object_,*) + ) + (optional + (relative_error_bound_, (const FT&)) + (p_rng_, (CGAL::Random*)) + (null_subdomain_index_,(Null)) + (construct_surface_patch_index_, + (Construct_surface_patch_index)) + ) + ) + using Impl_details::construct_pair_functor; /** - * @brief Constructor + * Backward-compatibility constructors, with `null_subdomain_index` as + * fourth parameter. + * @{ */ Labeled_mesh_domain_3(const Function& f, const Sphere_3& bounding_sphere, const FT& error_bound = FT(1e-3), - Null null = Null(), - CGAL::Random* p_rng = NULL); + Null null = Null_subdomain_index(), + CGAL::Random* p_rng = NULL) + : Impl_details(f, bounding_sphere, + error_bound, + construct_pair_functor(), + null, p_rng) {} Labeled_mesh_domain_3(const Function& f, const Bbox_3& bbox, const FT& error_bound = FT(1e-3), - Null null = Null(), - CGAL::Random* p_rng = NULL); + Null null = Null_subdomain_index(), + CGAL::Random* p_rng = NULL) + : Impl_details(f, bbox, + error_bound, + construct_pair_functor(), + null, p_rng) {} Labeled_mesh_domain_3(const Function& f, const Iso_cuboid_3& bbox, const FT& error_bound = FT(1e-3), - Null null = Null(), - CGAL::Random* p_rng = NULL); + Null null = Null_subdomain_index(), + CGAL::Random* p_rng = NULL) + : Impl_details(f, bbox, error_bound, + construct_pair_functor(), + null, p_rng) + {} + /** + * @} + */ - Labeled_mesh_domain_3(const Function& f, - const Sphere_3& bounding_sphere, - const FT& error_bound, - CGAL::Random* p_rng); - - Labeled_mesh_domain_3(const Function& f, - const Bbox_3& bbox, - const FT& error_bound, - CGAL::Random* p_rng); - - Labeled_mesh_domain_3(const Function& f, - const Iso_cuboid_3& bbox, - const FT& error_bound, - CGAL::Random* p_rng); - /// Destructor - virtual ~Labeled_mesh_domain_3() + /// Named constructors, for domains created from 3D images + /// @{ +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable: 4003) +#endif + BOOST_PARAMETER_MEMBER_FUNCTION( + (Labeled_mesh_domain_3), + static create_gray_image_mesh_domain, + parameters::tag, + (required + (image_, (const CGAL::Image_3&)) + ) + (optional + (iso_value_, *, 0) + (value_outside_, *, 0) + (relative_error_bound_, (const FT&), + FT(1e-3)) + (p_rng_, (CGAL::Random*), (CGAL::Random*)(0)) + (image_values_to_subdomain_indices_, *, + Null_functor()) + (null_subdomain_index_,*,Null_functor()) + (construct_surface_patch_index_, *, + Null_functor()) + ) + ) { - if(delete_rng_) - delete p_rng_; + namespace p = CGAL::parameters; + return Labeled_mesh_domain_3 + (create_gray_image_wrapper + (image_, + iso_value_, + image_values_to_subdomain_indices_, + value_outside_), + internal::Mesh_3::compute_bounding_box(image_), + p::relative_error_bound = relative_error_bound_, + p::p_rng = p_rng_, + p::null_subdomain_index = + create_null_subdomain_index(null_subdomain_index_), + p::construct_surface_patch_index = + create_construct_surface_patch_index(construct_surface_patch_index_)); } + BOOST_PARAMETER_MEMBER_FUNCTION( + (Labeled_mesh_domain_3), + static create_labeled_image_mesh_domain, + parameters::tag, + (required + (image_, (const CGAL::Image_3&)) + ) + (optional + (relative_error_bound_, (const FT&), + FT(1e-3)) + (value_outside_, *, 0) + (p_rng_, (CGAL::Random*), (CGAL::Random*)(0)) + (image_values_to_subdomain_indices_, *, + Null_functor()) + (null_subdomain_index_,*,Null_functor()) + (construct_surface_patch_index_, *, + Null_functor()) + ) + ) + { + namespace p = CGAL::parameters; + return Labeled_mesh_domain_3 + (create_labeled_image_wrapper + (image_, + image_values_to_subdomain_indices_, + value_outside_), + internal::Mesh_3::compute_bounding_box(image_), + p::relative_error_bound = relative_error_bound_, + p::p_rng = p_rng_, + p::null_subdomain_index = + create_null_subdomain_index(null_subdomain_index_), + p::construct_surface_patch_index = + create_construct_surface_patch_index(construct_surface_patch_index_)); + } + BOOST_PARAMETER_MEMBER_FUNCTION( + (Labeled_mesh_domain_3), + static create_implicit_mesh_domain, + parameters::tag, + (required + (function_, *) + (bounding_object_,*) + ) + (optional + (relative_error_bound_, (const FT&), + FT(1e-3)) + (p_rng_, (CGAL::Random*), (CGAL::Random*)(0)) + (null_subdomain_index_,*,Null_functor()) + (construct_surface_patch_index_, *, + Null_functor()) + ) + ) + { + namespace p = CGAL::parameters; + return Labeled_mesh_domain_3 + (make_implicit_to_labeling_function_wrapper(function_), + bounding_object_, + p::relative_error_bound = relative_error_bound_, + p::p_rng = p_rng_, + p::null_subdomain_index = + create_null_subdomain_index(null_subdomain_index_), + p::construct_surface_patch_index = + create_construct_surface_patch_index(construct_surface_patch_index_)); + } + +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + /// @} /** * Constructs a set of \ccc{n} points on the surface, and output them to @@ -179,7 +516,7 @@ public: * Returns a bounding box of the domain */ Bbox_3 bbox() const { - return bbox_.bbox(); + return this->bbox_.bbox(); } /** @@ -344,7 +681,7 @@ public: // Cannot be const: those values are modified below. Subdomain_index value_at_p1 = r_domain_.function_(p1); Subdomain_index value_at_p2 = r_domain_.function_(p2); - Subdomain_index value_at_mid = r_domain_.function_(mid,true); + Subdomain_index value_at_mid = r_domain_.function_(mid); // If both extremities are in the same subdomain, // there is no intersection. @@ -390,7 +727,7 @@ public: } mid = midpoint(p1, p2); - value_at_mid = r_domain_.function_(mid,true); + value_at_mid = r_domain_.function_(mid); } } @@ -468,29 +805,15 @@ public: // ----------------------------------- -private: +protected: /// Returns Surface_patch_index from \c i and \c j Surface_patch_index make_surface_index(const Subdomain_index i, - const Subdomain_index j) const + const Subdomain_index j) const { - if ( i < j ) return Surface_patch_index(i,j); - else return Surface_patch_index(j,i); - } - - /// Returns squared error bound from \c bbox and \c error - FT squared_error_bound(const Iso_cuboid_3& bbox, const FT& error) const - { - typename BGT::Compute_squared_distance_3 squared_distance = - BGT().compute_squared_distance_3_object(); - return squared_distance((bbox.min)(), (bbox.max)())*error*error/4; - } - - /// Returns squared error bound from \c sphere and \c error - FT squared_error_bound(const Sphere_3& sphere, const FT& error) const - { - typename BGT::Compute_squared_radius_3 squared_radius = - BGT().compute_squared_radius_3_object(); - return squared_radius(sphere)*error*error; + if(i < j) + return this->cstr_s_p_index(i, j); + else + return this->cstr_s_p_index(j, i); } /// Returns the bounding sphere of an Iso_cuboid_3 @@ -500,39 +823,118 @@ private: return sphere((bbox.min)(), (bbox.max)()); } - /// Returns and Iso_cuboid_3 from a Bbox_3 - Iso_cuboid_3 iso_cuboid(const Bbox_3& bbox) + template + static + Function + create_gray_image_wrapper_with_known_word_type + (const CGAL::Image_3& image, + const FT& iso_value, + const Functor& image_values_to_subdomain_indices, + const FT2& value_outside) { - const Point_3 p_min(bbox.xmin(), bbox.ymin(), bbox.zmin()); - const Point_3 p_max(bbox.xmax(), bbox.ymax(), bbox.zmax()); + using internal::Mesh_3::Create_gray_image_values_to_subdomain_indices; + typedef Create_gray_image_values_to_subdomain_indices C_i_v_t_s_i; + typedef typename C_i_v_t_s_i::type Image_values_to_subdomain_indices; + Image_values_to_subdomain_indices transform_fct = + C_i_v_t_s_i()(image_values_to_subdomain_indices, iso_value); - return Iso_cuboid_3(p_min,p_max); + typedef Mesh_3::Image_to_labeled_function_wrapper Wrapper; + return Wrapper(image, + transform_fct, + transform_fct(value_outside)); + } + + template + static + Function + create_gray_image_wrapper(const CGAL::Image_3& image, + const FT& iso_value, + const Functor& image_values_to_subdomain_indices, + const FT2& value_outside) + { + CGAL_IMAGE_IO_CASE(image.image(), + return create_gray_image_wrapper_with_known_word_type + (image, + iso_value, + image_values_to_subdomain_indices, + value_outside); + ); + CGAL_error_msg("This place should never be reached, because it would mean " + "the image word type is a type that is not handled by " + "CGAL_ImageIO."); + return Function(); + } + + template + static + Function + create_labeled_image_wrapper_with_known_word_type + (const CGAL::Image_3& image, + const Functor& image_values_to_subdomain_indices, + const FT& value_outside) + { + using internal::Mesh_3::Create_labeled_image_values_to_subdomain_indices; + typedef Create_labeled_image_values_to_subdomain_indices C_i_v_t_s_i; + typedef typename C_i_v_t_s_i::type Image_values_to_subdomain_indices; + Image_values_to_subdomain_indices transform_fct = + C_i_v_t_s_i()(image_values_to_subdomain_indices); + + typedef Mesh_3::Image_to_labeled_function_wrapper Wrapper; + return Wrapper(image, + transform_fct, + transform_fct(value_outside)); + } + + template + static + Function + create_labeled_image_wrapper(const CGAL::Image_3& image, + const Functor& image_values_to_subdomain_indices, + const FT& value_outside) + { + CGAL_IMAGE_IO_CASE(image.image(), + return create_labeled_image_wrapper_with_known_word_type + (image, + image_values_to_subdomain_indices, + value_outside); + ); + CGAL_error_msg("This place should never be reached, because it would mean " + "the image word type is a type that is not handled by " + "CGAL_ImageIO."); + return Function(); + } + + static + Construct_surface_patch_index + create_construct_surface_patch_index(const Null_functor&) { + return Impl_details::construct_pair_functor(); + } + + template + static + Construct_surface_patch_index + create_construct_surface_patch_index(const Functor& functor) { + return functor; + } + + static Null create_null_subdomain_index(const Null_functor&) { + return Null_subdomain_index(); + } + + template + static Null create_null_subdomain_index(const Functor& functor) { + return functor; } -protected: /// Returns bounding box - const Iso_cuboid_3& bounding_box() const { return bbox_; } - -private: - /// The function which answers subdomain queries - const Function function_; - /// The bounding box - const Iso_cuboid_3 bbox_; - /// The functor that decides which sub-domain indices correspond to the - /// outside of the domain. - Null null; - /// The random number generator used by Construct_initial_points - CGAL::Random* p_rng_; - bool delete_rng_; - /// Error bound relative to sphere radius - FT squared_error_bound_; - - -private: - // Disabled copy constructor & assignment operator - typedef Labeled_mesh_domain_3 Self; - Labeled_mesh_domain_3(const Self& src); - Self& operator=(const Self& src); + const Iso_cuboid_3& bounding_box() const { return this->bbox_; } }; // end class Labeled_mesh_domain_3 @@ -542,109 +944,12 @@ private: //------------------------------------------------------- // Method implementation //------------------------------------------------------- -template -Labeled_mesh_domain_3::Labeled_mesh_domain_3( - const F& f, - const Sphere_3& bounding_sphere, - const FT& error_bound, - Null null /* = Null() */, - CGAL::Random* p_rng) -: function_(f) -, bbox_(iso_cuboid(bounding_sphere.bbox())) -, null(null) -, p_rng_(p_rng == 0 ? new CGAL::Random(0) : p_rng) -, delete_rng_(p_rng == 0) -, squared_error_bound_(squared_error_bound(bounding_sphere,error_bound)) -{ -} - -template -Labeled_mesh_domain_3::Labeled_mesh_domain_3( - const F& f, - const Bbox_3& bbox, - const FT& error_bound, - Null null /* = Null() */, - CGAL::Random* p_rng) -: function_(f) -, bbox_(iso_cuboid(bbox)) -, null(null) -, p_rng_(p_rng == 0 ? new CGAL::Random(0) : p_rng) -, delete_rng_(p_rng == 0) -, squared_error_bound_(squared_error_bound(bbox_,error_bound)) -{ -} - -template -Labeled_mesh_domain_3::Labeled_mesh_domain_3( - const F& f, - const Iso_cuboid_3& bbox, - const FT& error_bound, - Null null /* = Null() */, - CGAL::Random* p_rng) -: function_(f) -, bbox_(bbox) -, null(null) -, p_rng_(p_rng == 0 ? new CGAL::Random(0) : p_rng) -, delete_rng_(p_rng == 0) -, squared_error_bound_(squared_error_bound(bbox_,error_bound)) -{ -} - - - - -template -Labeled_mesh_domain_3::Labeled_mesh_domain_3( - const F& f, - const Sphere_3& bounding_sphere, - const FT& error_bound, - CGAL::Random* p_rng) -: function_(f) -, bbox_(iso_cuboid(bounding_sphere.bbox())) -, null(Null()) -, p_rng_(p_rng == 0 ? new CGAL::Random(0) : p_rng) -, delete_rng_(p_rng == 0) -, squared_error_bound_(squared_error_bound(bounding_sphere,error_bound)) -{ -} - -template -Labeled_mesh_domain_3::Labeled_mesh_domain_3( - const F& f, - const Bbox_3& bbox, - const FT& error_bound, - CGAL::Random* p_rng) -: function_(f) -, bbox_(iso_cuboid(bbox)) -, null(Null()) -, p_rng_(p_rng == 0 ? new CGAL::Random(0) : p_rng) -, delete_rng_(p_rng == 0) -, squared_error_bound_(squared_error_bound(bbox_,error_bound)) -{ -} - -template -Labeled_mesh_domain_3::Labeled_mesh_domain_3( - const F& f, - const Iso_cuboid_3& bbox, - const FT& error_bound, - CGAL::Random* p_rng) -: function_(f) -, bbox_(bbox) -, null(Null()) -, p_rng_(p_rng == 0 ? new CGAL::Random(0) : p_rng) -, delete_rng_(p_rng == 0) -, squared_error_bound_(squared_error_bound(bbox_,error_bound)) -{ -} - - -template +template template OutputIterator -Labeled_mesh_domain_3::Construct_initial_points::operator()( - OutputIterator pts, - const int nb_points) const +Labeled_mesh_domain_3:: +Construct_initial_points::operator()(OutputIterator pts, + const int nb_points) const { // Create point_iterator on and in bounding_sphere typedef Random_points_on_sphere_3 Random_points_on_sphere_3; diff --git a/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h b/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h index c0ce67121ee..784611a0195 100644 --- a/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h +++ b/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h @@ -1030,7 +1030,7 @@ private: * A functor which returns true if a given handle is in c3t3 */ template - class Is_in_c3t3 : public CGAL::unary_function + class Is_in_c3t3 : public CGAL::cpp98::unary_function { public: Is_in_c3t3(const C3T3& c3t3) : c3t3_(c3t3) { } @@ -1047,7 +1047,7 @@ private: * A functor which answers true if a Cell_handle is a sliver */ template - struct Is_sliver : public CGAL::unary_function + struct Is_sliver : public CGAL::cpp98::unary_function { Is_sliver(const C3T3& c3t3, const SliverCriterion& criterion, @@ -1252,11 +1252,6 @@ private: facet.first->set_facet_surface_center(facet.second,surface_center); facet_m.first->set_facet_surface_center(facet_m.second,surface_center); } - else - { - facet.first->set_facet_surface_center(facet.second,Bare_point()); - facet_m.first->set_facet_surface_center(facet_m.second,Bare_point()); - } } return surface; @@ -1320,7 +1315,7 @@ private: */ template class Sliver_criterion_value - : public CGAL::unary_function + : public CGAL::cpp98::unary_function { public: Sliver_criterion_value(const Tr& tr, @@ -1687,9 +1682,27 @@ private: /** * Returns the least square plane from v, using adjacent surface points */ - Plane_3 get_least_square_surface_plane(const Vertex_handle& v, - Bare_point& ref_point, - Surface_patch_index index = Surface_patch_index()) const; + boost::optional + get_least_square_surface_plane(const Vertex_handle& v, + Bare_point& ref_point, + Surface_patch_index index = Surface_patch_index()) const; + + /** + * @brief Project \c p on surface, using incident facets of \c v + * @param p The point to project + * @param v The vertex from which p was moved + * @param index The index of the surface patch where v lies, if known. + * @return a boost::optional with the projected point if the projection + * was possible, or boost::none + * + * \c p is projected as follows using normal of least square fitting plane + * on \c v incident surface points. If \c index is specified, only + * surface points that are on the same surface patch are used to compute + * the fitting plane. + */ + boost::optional + project_on_surface_if_possible(const Bare_point& p, const Vertex_handle& v, + Surface_patch_index index = Surface_patch_index()) const; /** * @brief Returns the projection of \c p, using direction of @@ -2667,7 +2680,6 @@ C3T3_helpers:: rebuild_restricted_delaunay(OutdatedCells& outdated_cells, Moving_vertices_set& moving_vertices) { - typename Gt::Equal_3 equal = tr_.geom_traits().equal_3_object(); typename OutdatedCells::iterator first_cell = outdated_cells.begin(); typename OutdatedCells::iterator last_cell = outdated_cells.end(); Update_c3t3 updater(domain_,c3t3_); @@ -2766,15 +2778,16 @@ rebuild_restricted_delaunay(OutdatedCells& outdated_cells, it != vertex_to_proj.end() ; ++it ) { - Bare_point new_pos = project_on_surface(wp2p_((*it)->point()),*it); + boost::optional opt_new_pos = + project_on_surface(wp2p_((*it)->point()),*it); - if ( ! equal(new_pos, Bare_point()) ) + if ( opt_new_pos ) { //freezing needs 'erase' to be done before the vertex is actually destroyed // Update moving vertices (it becomes new_vertex) moving_vertices.erase(*it); - Vertex_handle new_vertex = update_mesh(p2wp_(new_pos),*it); + Vertex_handle new_vertex = update_mesh(p2wp_(*opt_new_pos),*it); c3t3_.set_dimension(new_vertex,2); moving_vertices.insert(new_vertex); @@ -2873,15 +2886,16 @@ rebuild_restricted_delaunay(ForwardIterator first_cell, it != vertex_to_proj.end() ; ++it ) { - Bare_point new_pos = project_on_surface(wp2p_((it->first)->point()),it->first,it->second); + boost::optional opt_new_pos = + project_on_surface(wp2p_((it->first)->point()),it->first,it->second); - if ( ! equal(new_pos, Bare_point()) ) + if ( opt_new_pos ) { //freezing needs 'erase' to be done before the vertex is actually destroyed // Update moving vertices (it becomes new_vertex) moving_vertices.erase(it->first); - Vertex_handle new_vertex = update_mesh(p2wp_(new_pos), it->first); + Vertex_handle new_vertex = update_mesh(p2wp_(*opt_new_pos), it->first); c3t3_.set_dimension(new_vertex,2); moving_vertices.insert(new_vertex); @@ -3333,7 +3347,7 @@ project_on_surface_aux(const Bare_point& p, template -typename C3T3_helpers::Plane_3 +boost::optional::Plane_3> C3T3_helpers:: get_least_square_surface_plane(const Vertex_handle& v, Bare_point& reference_point, @@ -3373,7 +3387,7 @@ get_least_square_surface_plane(const Vertex_handle& v, // In some cases point is not a real surface point if ( surface_point_vector.empty() ) - return Plane_3(); + return boost::none; // Compute least square fitting plane Plane_3 plane; @@ -3399,25 +3413,39 @@ C3T3_helpers:: project_on_surface(const Bare_point& p, const Vertex_handle& v, Surface_patch_index index) const +{ + boost::optional opt_point = + project_on_surface_if_possible(p, v, index); + if(opt_point) return *opt_point; + else return p; +} + + +template +boost::optional::Bare_point> +C3T3_helpers:: +project_on_surface_if_possible(const Bare_point& p, + const Vertex_handle& v, + Surface_patch_index index) const { typename Gt::Equal_3 equal = tr_.geom_traits().equal_3_object(); // return domain_.project_on_surface(p); // Get plane - Bare_point reference_point(CGAL::ORIGIN); - Plane_3 plane = get_least_square_surface_plane(v,reference_point, index); + Bare_point reference_point; + boost::optional opt_plane = + get_least_square_surface_plane(v,reference_point, index); - if ( equal(reference_point, CGAL::ORIGIN) ) - return p; + if(!opt_plane) return boost::none; // Project if ( ! equal(p, wp2p_(v->point())) ) return project_on_surface_aux(p, wp2p_(v->point()), - plane.orthogonal_vector()); + opt_plane->orthogonal_vector()); else return project_on_surface_aux(p, reference_point, - plane.orthogonal_vector()); + opt_plane->orthogonal_vector()); } diff --git a/Mesh_3/include/CGAL/Mesh_3/Image_to_labeled_function_wrapper.h b/Mesh_3/include/CGAL/Mesh_3/Image_to_labeled_function_wrapper.h index 745c059784b..70dbcd7de06 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Image_to_labeled_function_wrapper.h +++ b/Mesh_3/include/CGAL/Mesh_3/Image_to_labeled_function_wrapper.h @@ -34,7 +34,8 @@ #include #include - +#include +#include namespace CGAL { @@ -47,25 +48,27 @@ namespace Mesh_3 { * N. Uses trilinear interpolation. * Note: Image has to be labeled with unsigned char */ -template, bool labeled_image = true, bool use_trilinear_interpolation=true> class Image_to_labeled_function_wrapper { public: + typedef CGAL::cpp11::function + Image_values_to_labels; + // Types typedef Return_type return_type; typedef Image_word_type word_type; - typedef typename BGT::Point_3 Point_3; + typedef CGAL::Image_3 Image_; /// Constructor - Image_to_labeled_function_wrapper(const Image_& image, - const Transform& transform = Transform(), - const Return_type value_outside = 0) + Image_to_labeled_function_wrapper + (const Image_& image, + Image_values_to_labels transform = Identity(), + const Interpolation_type value_outside = Interpolation_type()) : r_im_(image) , transform(transform) , value_outside(value_outside) @@ -82,7 +85,8 @@ public: * @param p the input point * @return the label at point \c p */ - return_type operator()(const Point_3& p, const bool = true) const + template + return_type operator()(const Point_3& p) const { return eval(p, CGAL::Boolean_tag(), @@ -90,38 +94,41 @@ public: } private: + template return_type eval(const Point_3& p, CGAL::Tag_true /*trilinear*/, CGAL::Tag_true /*labeled*/) const { return static_cast(transform( - r_im_.template labellized_trilinear_interpolation( - CGAL::to_double(p.x()), - CGAL::to_double(p.y()), - CGAL::to_double(p.z()), + r_im_.template labellized_trilinear_interpolation( + CGAL::to_double(p.x()-r_im_.image()->tx), + CGAL::to_double(p.y()-r_im_.image()->ty), + CGAL::to_double(p.z()-r_im_.image()->tz), value_outside))); } + template return_type eval(const Point_3& p, CGAL::Tag_true /*trilinear*/, CGAL::Tag_false /*labeled*/) const { return transform( - r_im_.template trilinear_interpolation( - CGAL::to_double(p.x()), - CGAL::to_double(p.y()), - CGAL::to_double(p.z()), + r_im_.template trilinear_interpolation( + CGAL::to_double(p.x()-r_im_.image()->tx), + CGAL::to_double(p.y()-r_im_.image()->ty), + CGAL::to_double(p.z()-r_im_.image()->tz), value_outside)); } - template + template return_type eval(const Point_3& p, CGAL::Tag_false /*trilinear*/, Labeled_tag /*labeled*/) const { - const std::ptrdiff_t px = static_cast(p.x()/r_im_.vx()); - const std::ptrdiff_t py = static_cast(p.y()/r_im_.vy()); - const std::ptrdiff_t pz = static_cast(p.z()/r_im_.vz()); + const std::ptrdiff_t px = static_cast((p.x()-r_im_.image()->tx)/r_im_.vx()); + const std::ptrdiff_t py = static_cast((p.y()-r_im_.image()->ty)/r_im_.vy()); + const std::ptrdiff_t pz = static_cast((p.z()-r_im_.image()->tz)/r_im_.vz()); const std::ptrdiff_t dimx = static_cast(r_im_.xdim()); const std::ptrdiff_t dimy = static_cast(r_im_.ydim()); @@ -144,8 +151,8 @@ private: /// Labeled image to wrap const Image_& r_im_; - const Transform transform; - const Return_type value_outside; + const Image_values_to_labels transform; + const Interpolation_type value_outside; }; // end class Image_to_labeled_function_wrapper diff --git a/Mesh_3/include/CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h b/Mesh_3/include/CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h deleted file mode 100644 index 5349a6ba5e3..00000000000 --- a/Mesh_3/include/CGAL/Mesh_3/Implicit_to_labeled_function_wrapper.h +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) 2009 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// You can redistribute it and/or modify it under the terms of the GNU -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0+ -// -// -// Author(s) : Stéphane Tayeb -// -//****************************************************************************** -// File Description : -// Implicit_to_labeling_function_wrapper and -// Implicit_vector_to_labeling_function_wrapper class declaration -// and implementation. -// -// See classes description to have more information. -//****************************************************************************** - -#ifndef CGAL_MESH_3_IMPLICIT_TO_LABELED_FUNCTION_WRAPPER_H -#define CGAL_MESH_3_IMPLICIT_TO_LABELED_FUNCTION_WRAPPER_H - -#include - -#include - -#define CGAL_DEPRECATED_HEADER "" -#define CGAL_REPLACEMENT_HEADER "" -#include - -#include - -namespace CGAL { - -namespace Mesh_3 { - -#include - -/** - * @class Implicit_to_labeled_function_wrapper - * - * This class is designed to wrap an implicit function which describes a domain - * by [p is inside if f(p)<0] to a function which takes its values into {0,1}. - * f(p)=0 means that p is outside the domain. - */ -template -class Implicit_to_labeled_function_wrapper -{ -public: - // Types - typedef int return_type; - typedef typename BGT::Point_3 Point_3; - - /// Constructor - Implicit_to_labeled_function_wrapper(const Function_& f) - : r_f_(f) {} - - // Default copy constructor and assignment operator are ok - - /// Destructor - ~Implicit_to_labeled_function_wrapper() {} - - /// Operator () - return_type operator()(const Point_3& p, const bool = true) const - { - return ( (r_f_(p)<0) ? 1 : 0 ); - } - -private: - /// Function to wrap - const Function_& r_f_; - -}; // end class Implicit_to_labeled_function_wrapper - - - -/** - * \deprecated - * - * @class Implicit_vector_to_labeled_function_wrapper - * - * Wraps a set of implicit function [f1,f2,...] to one function F which - * takes its values into N. - * - * Let p be a point. - * F(p) = 0b000000(f2(p)<0)(f1(p)<0) - * - * It can handle at most 8 functions. - */ -template -class Implicit_vector_to_labeled_function_wrapper -{ -public: - // Types - typedef int return_type; - typedef std::vector Function_vector; - typedef typename BGT::Point_3 Point_3; - - /// Constructor - Implicit_vector_to_labeled_function_wrapper(const std::vector& v) - : function_vector_(v) - { - if ( v.size() > 8 ) - { - CGAL_error_msg("We support at most 8 functions !"); - } - } - - // Default copy constructor and assignment operator are ok - - /// Destructor - ~Implicit_vector_to_labeled_function_wrapper() {} - - /// Operator () - return_type operator()(const Point_3& p, const bool = true) const - { - const int nb_func = static_cast(function_vector_.size()); - char bits = 0; - for ( int i = 0 ; i < nb_func ; ++i ) - { - // Insert value into bits : we compute fi(p) and insert result at - // bit i of bits - bits = char(bits | ( ((*function_vector_[i])(p) < 0) << i )); - } - - return ( static_cast(bits) ); - } - -private: - /// Functions to wrap - const Function_vector function_vector_; - -}; // end class Implicit_to_labeled_function_wrapper - -} // end namespace Mesh_3 - -} // end namespace CGAL - - - -#include - -#endif // CGAL_MESH_3_IMPLICIT_TO_LABELED_FUNCTION_WRAPPER_H diff --git a/Mesh_3/include/CGAL/Mesh_3/Labeled_mesh_domain_3.h b/Mesh_3/include/CGAL/Mesh_3/Labeled_mesh_domain_3.h deleted file mode 100644 index 1c8c1af7d9e..00000000000 --- a/Mesh_3/include/CGAL/Mesh_3/Labeled_mesh_domain_3.h +++ /dev/null @@ -1,636 +0,0 @@ -// Copyright (c) 2009 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// You can redistribute it and/or modify it under the terms of the GNU -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0+ -// -// -// Author(s) : Stéphane Tayeb -// -//****************************************************************************** -// File Description : -// class Labeled_mesh_domain_3. See class description. -//****************************************************************************** - -#ifndef CGAL_MESH_3_LABELED_MESH_DOMAIN_3_H -#define CGAL_MESH_3_LABELED_MESH_DOMAIN_3_H - -#include - -#include - -#define CGAL_DEPRECATED_HEADER "" -#define CGAL_REPLACEMENT_HEADER "" -#include - -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include - -namespace CGAL { - -namespace Mesh_3 { - -/** - * \class Labeled_mesh_domain_3 - * - * Function f must take his values into N. - * Let p be a Point. - * - f(p)=0 means that p is outside domain. - * - f(p)=a, a!=0 means that p is inside subdomain a. - * - * Any boundary facet is labelled , a, where b!=0. - */ -template -class Labeled_mesh_domain_3 -{ -public: - /// Geometric object types - typedef typename BGT::Point_3 Point_3; - typedef typename BGT::Segment_3 Segment_3; - typedef typename BGT::Ray_3 Ray_3; - typedef typename BGT::Line_3 Line_3; - typedef typename BGT::Vector_3 Vector_3; - typedef typename BGT::Sphere_3 Sphere_3; - typedef CGAL::Bbox_3 Bbox_3; - - typedef typename BGT::Iso_cuboid_3 Iso_cuboid_3; - -public: - // Kernel_traits compatibility - typedef BGT R; - - //------------------------------------------------------- - // Index Types - //------------------------------------------------------- - /// Type of indexes for cells of the input complex - typedef typename Function::return_type Subdomain_index; - typedef boost::optional Subdomain; - /// Type of indexes for surface patch of the input complex - typedef std::pair Surface_patch_index; - typedef boost::optional Surface_patch; - /// Type of indexes to characterize the lowest dimensional face of the input - /// complex on which a vertex lie - typedef boost::variant Index; - typedef CGAL::cpp11::tuple Intersection; - - - typedef typename BGT::FT FT; - typedef BGT Geom_traits; - - /** - * @brief Constructor - */ - Labeled_mesh_domain_3(const Function& f, - const Sphere_3& bounding_sphere, - const FT& error_bound = FT(1e-3), - CGAL::Random* p_rng = NULL); - - Labeled_mesh_domain_3(const Function& f, - const Bbox_3& bbox, - const FT& error_bound = FT(1e-3), - CGAL::Random* p_rng = NULL); - - /// Destructor - virtual ~Labeled_mesh_domain_3() - { - if(delete_rng_) - delete p_rng_; - } - - /** - * Returns a bounding box of the domain - */ - Bbox_3 bbox() const { - return this->bbox_.bbox(); - } - - /** - * Constructs a set of \ccc{n} points on the surface, and output them to - * the output iterator \ccc{pts} whose value type is required to be - * \ccc{std::pair}. - */ - struct Construct_initial_points - { - Construct_initial_points(const Labeled_mesh_domain_3& domain) - : r_domain_(domain) {} - - template - OutputIterator operator()(OutputIterator pts, const int n = 12) const; - - private: - const Labeled_mesh_domain_3& r_domain_; - }; - - /// Returns Construct_initial_points object - Construct_initial_points construct_initial_points_object() const - { - return Construct_initial_points(*this); - } - - /** - * Returns true if point~\ccc{p} is in the domain. If \ccc{p} is in the - * domain, the parameter index is set to the index of the subdomain - * including $p$. It is set to the default value otherwise. - */ - struct Is_in_domain - { - Is_in_domain(const Labeled_mesh_domain_3& domain) : r_domain_(domain) {} - - Subdomain operator()(const Point_3& p) const - { - // f(p)==0 means p is outside the domain - Subdomain_index index = (r_domain_.function_)(p); - if ( Subdomain_index() == index ) - return Subdomain(); - else - return Subdomain(index); - } - private: - const Labeled_mesh_domain_3& r_domain_; - }; - - /// Returns Is_in_domain object - Is_in_domain is_in_domain_object() const { return Is_in_domain(*this); } - - /** - * Returns true is the element \ccc{type} intersect properly any of the - * surface patches describing the either the domain boundary or some - * subdomain boundary. - * \ccc{Type} is either \ccc{Segment_3}, \ccc{Ray_3} or \ccc{Line_3}. - * Parameter index is set to the index of the intersected surface patch - * if \ccc{true} is returned and to the default \ccc{Surface_patch_index} - * value otherwise. - */ - struct Do_intersect_surface - { - Do_intersect_surface(const Labeled_mesh_domain_3& domain) - : r_domain_(domain) {} - - Surface_patch operator()(const Segment_3& s) const - { - return this->operator()(s.source(), s.target()); - } - - Surface_patch operator()(const Ray_3& r) const - { - return clip_to_segment(r); - } - - Surface_patch operator()(const Line_3& l) const - { - return clip_to_segment(l); - } - - private: - /// Returns true if points \c a & \c b do not belong to the same subdomain - /// \c index is set to the surface index of subdomains f(a), f(b) - Surface_patch operator()(const Point_3& a, const Point_3& b) const - { - // If f(a) != f(b), then [a,b] intersects some surface. Here we consider - // [a,b] intersects surface_patch labelled (or ). - // It may be false, further rafinement will improve precision - const Subdomain_index value_a = r_domain_.function_(a); - const Subdomain_index value_b = r_domain_.function_(b); - - if ( value_a != value_b ) - return Surface_patch(r_domain_.make_surface_index(value_a, value_b)); - else - return Surface_patch(); - } - - /** - * Clips \c query to a segment \c s, and call operator()(s) - */ - template - Surface_patch clip_to_segment(const Query& query) const - { - typename cpp11::result_of::type - clipped = CGAL::intersection(query, r_domain_.bbox_); - - if(clipped) -#if CGAL_INTERSECTION_VERSION > 1 - if(const Segment_3* s = boost::get(&*clipped)) - return this->operator()(*s); -#else - if(const Segment_3* s = object_cast(&clipped)) - return this->operator()(*s); -#endif - - return Surface_patch(); - } - - private: - const Labeled_mesh_domain_3& r_domain_; - }; - - /// Returns Do_intersect_surface object - Do_intersect_surface do_intersect_surface_object() const - { - return Do_intersect_surface(*this); - } - - /** - * Returns a point in the intersection of the primitive \ccc{type} - * with some boundary surface. - * \ccc{Type1} is either \ccc{Segment_3}, \ccc{Ray_3} or \ccc{Line_3}. - * The integer \ccc{dimension} is set to the dimension of the lowest - * dimensional face in the input complex containing the returned point, and - * \ccc{index} is set to the index to be stored at a mesh vertex lying - * on this face. - */ - struct Construct_intersection - { - Construct_intersection(const Labeled_mesh_domain_3& domain) - : r_domain_(domain) {} - - Intersection operator()(const Segment_3& s) const - { -#ifndef CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 - CGAL_precondition(r_domain_.do_intersect_surface_object()(s)); -#endif // NOT CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3 - return this->operator()(s.source(),s.target()); - } - - Intersection operator()(const Ray_3& r) const - { - return clip_to_segment(r); - } - - Intersection operator()(const Line_3& l) const - { - return clip_to_segment(l); - } - - private: - /** - * Returns a point in the intersection of [a,b] with the surface - * \c a must be the source point, and \c b the out point. It's important - * because it drives bisection cuts. - * Indeed, the returned point is the first intersection from \c [a,b] - * with a subdomain surface. - */ - Intersection operator()(const Point_3& a, const Point_3& b) const - { - // Functors - typename BGT::Compute_squared_distance_3 squared_distance = - BGT().compute_squared_distance_3_object(); - typename BGT::Construct_midpoint_3 midpoint = - BGT().construct_midpoint_3_object(); - - // Non const points - Point_3 p1 = a; - Point_3 p2 = b; - Point_3 mid = midpoint(p1, p2); - - // Cannot be const: those values are modified below. - Subdomain_index value_at_p1 = r_domain_.function_(p1); - Subdomain_index value_at_p2 = r_domain_.function_(p2); - Subdomain_index value_at_mid = r_domain_.function_(mid,true); - - // If both extremities are in the same subdomain, - // there is no intersection. - // This should not happen... - if( value_at_p1 == value_at_p2 ) - { - return Intersection(); - } - - // Construct the surface patch index and index from the values at 'a' - // and 'b'. Even if the bissection find out a different pair of - // values, the reported index will be constructed from the initial - // values. - const Surface_patch_index sp_index = - r_domain_.make_surface_index(value_at_p1, value_at_p2); - const Index index = r_domain_.index_from_surface_patch_index(sp_index); - - // Else lets find a point (by bisection) - // Bisection ends when the point is near than error bound from surface - while(true) - { - // If the two points are enough close, then we return midpoint - if ( squared_distance(p1, p2) < r_domain_.squared_error_bound_ ) - { - CGAL_assertion(value_at_p1 != value_at_p2); - return Intersection(mid, index, 2); - } - - // Else we must go on - // Here we consider that p1(a) is the source point. Thus, we keep p1 and - // change p2 if f(p1)!=f(p2). - // That allows us to find the first intersection from a of [a,b] with - // a surface. - if ( value_at_p1 != value_at_mid ) - { - p2 = mid; - value_at_p2 = value_at_mid; - } - else - { - p1 = mid; - value_at_p1 = value_at_mid; - } - - mid = midpoint(p1, p2); - value_at_mid = r_domain_.function_(mid,true); - } - } - - /// Clips \c query to a segment \c s, and call operator()(s) - template - Intersection clip_to_segment(const Query& query) const - { - typename cpp11::result_of::type - clipped = CGAL::intersection(query, r_domain_.bbox_); - - if(clipped) -#if CGAL_INTERSECTION_VERSION > 1 - if(const Segment_3* s = boost::get(&*clipped)) - return this->operator()(*s); -#else - if(const Segment_3* s = object_cast(&clipped)) - return this->operator()(*s); -#endif - - return Intersection(); - } - - private: - const Labeled_mesh_domain_3& r_domain_; - }; - - /// Returns Construct_intersection object - Construct_intersection construct_intersection_object() const - { - return Construct_intersection(*this); - } - - /** - * Returns the index to be stored in a vertex lying on the surface identified - * by \c index. - */ - Index index_from_surface_patch_index(const Surface_patch_index& index) const - { return Index(index); } - - /** - * Returns the index to be stored in a vertex lying in the subdomain - * identified by \c index. - */ - Index index_from_subdomain_index(const Subdomain_index& index) const - { return Index(index); } - - /** - * Returns the \c Surface_patch_index of the surface patch - * where lies a vertex with dimension 2 and index \c index. - */ - Surface_patch_index surface_patch_index(const Index& index) const - { return boost::get(index); } - - /** - * Returns the index of the subdomain containing a vertex - * with dimension 3 and index \c index. - */ - Subdomain_index subdomain_index(const Index& index) const - { return boost::get(index); } - - // ----------------------------------- - // Backward Compatibility - // ----------------------------------- -#ifndef CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX - typedef Surface_patch_index Surface_index; - - Index index_from_surface_index(const Surface_index& index) const - { return index_from_surface_patch_index(index); } - - Surface_index surface_index(const Index& index) const - { return surface_patch_index(index); } -#endif // CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX - // ----------------------------------- - // End backward Compatibility - // ----------------------------------- - - -private: - /// Returns Surface_patch_index from \c i and \c j - Surface_patch_index make_surface_index(const Subdomain_index i, - const Subdomain_index j) const - { - if ( i < j ) return Surface_patch_index(i,j); - else return Surface_patch_index(j,i); - } - - /// Returns squared error bound from \c bbox and \c error - FT squared_error_bound(const Iso_cuboid_3& bbox, const FT& error) const - { - typename BGT::Compute_squared_distance_3 squared_distance = - BGT().compute_squared_distance_3_object(); - return squared_distance((bbox.min)(), (bbox.max)())*error*error/4; - } - - /// Returns squared error bound from \c sphere and \c error - FT squared_error_bound(const Sphere_3& sphere, const FT& error) const - { - typename BGT::Compute_squared_radius_3 squared_radius = - BGT().compute_squared_radius_3_object(); - return squared_radius(sphere)*error*error; - } - - /// Returns the bounding sphere of an Iso_cuboid_3 - Sphere_3 bounding_sphere(const Iso_cuboid_3& bbox) const - { - typename BGT::Construct_sphere_3 sphere = BGT().construct_sphere_3_object(); - return sphere((bbox.min)(), (bbox.max)()); - } - - /// Returns and Iso_cuboid_3 from a Bbox_3 - Iso_cuboid_3 iso_cuboid(const Bbox_3& bbox) - { - const Point_3 p_min(bbox.xmin(), bbox.ymin(), bbox.zmin()); - const Point_3 p_max(bbox.xmax(), bbox.ymax(), bbox.zmax()); - - return Iso_cuboid_3(p_min,p_max); - } - -protected: - /// Returns bounding box - const Iso_cuboid_3& bounding_box() const { return bbox_; } - -private: - /// The function which answers subdomain queries - const Function function_; - /// The bounding box - const Iso_cuboid_3 bbox_; - /// The random number generator used by Construct_initial_points - CGAL::Random* p_rng_; - bool delete_rng_; - /// Error bound relative to sphere radius - FT squared_error_bound_; - - -private: - // Disabled copy constructor & assignment operator - typedef Labeled_mesh_domain_3 Self; - Labeled_mesh_domain_3(const Self& src); - Self& operator=(const Self& src); - -}; // end class Labeled_mesh_domain_3 - - - - -//------------------------------------------------------- -// Method implementation -//------------------------------------------------------- -template -Labeled_mesh_domain_3::Labeled_mesh_domain_3( - const F& f, - const Sphere_3& bounding_sphere, - const FT& error_bound, - CGAL::Random* p_rng) -: function_(f) -, bbox_(iso_cuboid(bounding_sphere.bbox())) -, p_rng_(p_rng) -, delete_rng_(false) -, squared_error_bound_(squared_error_bound(bounding_sphere,error_bound)) -{ - // TODO : CGAL_ASSERT(0 < f(bounding_sphere.get_center()) ) ? - if(!p_rng_) - { - p_rng_ = new CGAL::Random(0); - delete_rng_ = true; - } -} - -template -Labeled_mesh_domain_3::Labeled_mesh_domain_3( - const F& f, - const Bbox_3& bbox, - const FT& error_bound, - CGAL::Random* p_rng) -: function_(f) -, bbox_(iso_cuboid(bbox)) -, p_rng_(p_rng) -, delete_rng_(false) -, squared_error_bound_(squared_error_bound(bbox_,error_bound)) -{ - // TODO : CGAL_ASSERT(0 < f(bounding_sphere.get_center()) ) ? - if(!p_rng_) - { - p_rng_ = new CGAL::Random(0); - delete_rng_ = true; - } -} - - -template -template -OutputIterator -Labeled_mesh_domain_3::Construct_initial_points::operator()( - OutputIterator pts, - const int nb_points) const -{ - // Create point_iterator on and in bounding_sphere - typedef Random_points_on_sphere_3 Random_points_on_sphere_3; - typedef Random_points_in_sphere_3 Random_points_in_sphere_3; - - - const FT squared_radius = BGT().compute_squared_radius_3_object()( - r_domain_.bounding_sphere(r_domain_.bbox_)); - - const double radius = std::sqrt(CGAL::to_double(squared_radius)); - - CGAL::Random& rng = *(r_domain_.p_rng_); - Random_points_on_sphere_3 random_point_on_sphere(radius, rng); - Random_points_in_sphere_3 random_point_in_sphere(radius, rng); - - // Get some functors - typename BGT::Construct_segment_3 segment_3 = - BGT().construct_segment_3_object(); - typename BGT::Construct_vector_3 vector_3 = - BGT().construct_vector_3_object(); - typename BGT::Construct_translated_point_3 translate = - BGT().construct_translated_point_3_object(); - typename BGT::Construct_center_3 center = BGT().construct_center_3_object(); - - // Get translation from origin to sphere center - Point_3 center_pt = center(r_domain_.bounding_sphere(r_domain_.bbox_)); - const Vector_3 sphere_translation = vector_3(CGAL::ORIGIN, center_pt); - - // Create nb_point points - int n = nb_points; -#ifdef CGAL_MESH_3_VERBOSE - std::cerr << "construct initial points:\n"; -#endif - while ( 0 != n ) - { - // Get a random segment - const Point_3 random_point = translate(*random_point_on_sphere, - sphere_translation); - const Segment_3 random_seg = segment_3(center_pt, random_point); - - // Add the intersection to the output if it exists - Surface_patch surface = r_domain_.do_intersect_surface_object()(random_seg); - if ( surface ) - { - const Point_3 intersect_pt = CGAL::cpp11::get<0>( - r_domain_.construct_intersection_object()(random_seg)); - *pts++ = std::make_pair(intersect_pt, - r_domain_.index_from_surface_patch_index(*surface)); - --n; - -#ifdef CGAL_MESH_3_VERBOSE - std::cerr << boost::format("\r \r" - "%1%/%2% initial point(s) found...") - % (nb_points - n) - % nb_points; -#endif - } - else - { - // Get a new random point into sphere as center of object - // It may be necessary if the center of the domain is empty, e.g. torus - // In general case, it is good for input point dispersion - ++random_point_in_sphere; - center_pt = translate(*random_point_in_sphere, sphere_translation); - } - ++random_point_on_sphere; - } - -#ifdef CGAL_MESH_3_VERBOSE - std::cerr << "\n"; -#endif - return pts; -} - - -} // end namespace Mesh_3 - -} // end namespace CGAL - -#include - -#endif // LABELLED_MESH_TRAITS_3_H_ diff --git a/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h b/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h index d0ee40fb0d7..a8e60a55232 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h @@ -461,6 +461,18 @@ refine_mesh(std::string dump_after_refine_surface_prefix) % r_tr.number_of_vertices() % nbsteps % cells_mesher_.debug_info() % (nbsteps / timer.time()); + if(refinement_stage == REFINE_FACETS && + facets_mesher_.is_algorithm_done()) + { + facets_mesher_.scan_edges(); + refinement_stage = REFINE_FACETS_AND_EDGES; + } + if(refinement_stage == REFINE_FACETS_AND_EDGES && + facets_mesher_.is_algorithm_done()) + { + facets_mesher_.scan_vertices(); + refinement_stage = REFINE_FACETS_AND_EDGES_AND_VERTICES; + } ++nbsteps; } std::cerr << std::endl; diff --git a/Mesh_3/include/CGAL/Mesh_3/Polyline_with_context.h b/Mesh_3/include/CGAL/Mesh_3/Polyline_with_context.h index 9b4312fbaa1..7a6fd6cc5ab 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Polyline_with_context.h +++ b/Mesh_3/include/CGAL/Mesh_3/Polyline_with_context.h @@ -61,9 +61,9 @@ struct Polyline_with_context */ template struct Extract_bare_polyline : - public CGAL::unary_function + public CGAL::cpp98::unary_function { - typedef CGAL::unary_function Base; + typedef CGAL::cpp98::unary_function Base; typedef typename Base::result_type result_type; typedef typename Base::argument_type argument_type; diff --git a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h index 37a2f7d0d71..7f2e66af85c 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h +++ b/Mesh_3/include/CGAL/Mesh_3/Protect_edges_sizing_field.h @@ -44,9 +44,12 @@ # include #endif #ifdef CGAL_MESH_3_DUMP_FEATURES_PROTECTION_ITERATIONS -#include +# include #endif #include +#if CGAL_MESH_3_PROTECTION_DEBUG +# include +#endif namespace CGAL { namespace Mesh_3 { diff --git a/Mesh_3/include/CGAL/Mesh_3/Slivers_exuder.h b/Mesh_3/include/CGAL/Mesh_3/Slivers_exuder.h index b4c072f2886..015a7bd6a30 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Slivers_exuder.h +++ b/Mesh_3/include/CGAL/Mesh_3/Slivers_exuder.h @@ -82,11 +82,11 @@ namespace Mesh_3 { // to use them. -- Laurent Rineau, 2007/07/27 template struct Second_of : - public CGAL::unary_function + public CGAL::cpp98::unary_function { - typedef CGAL::unary_function Base; + typedef CGAL::cpp98::unary_function Base; typedef typename Base::result_type result_type; typedef typename Base::argument_type argument_type; @@ -103,7 +103,7 @@ namespace Mesh_3 { // It is used in Slivers_exuder, to constructor a transform iterator. template class Min_distance_from_v : - public CGAL::unary_function + public CGAL::cpp98::unary_function { const Vertex_handle * v; const Gt& gt; diff --git a/Mesh_3/include/CGAL/Mesh_3/Triangulation_sizing_field.h b/Mesh_3/include/CGAL/Mesh_3/Triangulation_sizing_field.h index 91fff95bb75..315dcbb82f5 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Triangulation_sizing_field.h +++ b/Mesh_3/include/CGAL/Mesh_3/Triangulation_sizing_field.h @@ -117,7 +117,7 @@ private: * Used by boost transform iterator */ struct Extract_point : - public CGAL::unary_function + public CGAL::cpp98::unary_function { Weighted_point operator()(const typename Tr::Vertex& v) const { return v.point(); } }; diff --git a/Mesh_3/include/CGAL/Mesh_3/Worksharing_data_structures.h b/Mesh_3/include/CGAL/Mesh_3/Worksharing_data_structures.h index 4d647990344..ea346aae523 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Worksharing_data_structures.h +++ b/Mesh_3/include/CGAL/Mesh_3/Worksharing_data_structures.h @@ -300,6 +300,9 @@ public: : m_func(func), m_quality(quality) {} + virtual ~MeshRefinementWorkItem() + {} + void run() { m_func(); diff --git a/Mesh_3/include/CGAL/Mesh_3/config.h b/Mesh_3/include/CGAL/Mesh_3/config.h index f952e80cd7f..53b408812e3 100644 --- a/Mesh_3/include/CGAL/Mesh_3/config.h +++ b/Mesh_3/include/CGAL/Mesh_3/config.h @@ -67,22 +67,4 @@ # endif #endif -#if defined(__clang__) || (BOOST_GCC >= 40600) -# define CGAL_MESH_3_IGNORE_UNUSED_VARIABLES \ - _Pragma("GCC diagnostic ignored \"-Wunused-variable\"") \ - _Pragma("GCC diagnostic ignored \"-Wunused-parameter\"") -#else -# define CGAL_MESH_3_IGNORE_UNUSED_VARIABLES -#endif -#if __has_warning("-Wunneeded-internal-declaration") -# define CGAL_MESH_3_IGNORE_UNUSED_INTERNAL_DECLARATION \ - _Pragma("clang diagnostic ignored \"-Wunneeded-internal-declaration\"") -#else -# define CGAL_MESH_3_IGNORE_UNUSED_INTERNAL_DECLARATION -#endif - -#define CGAL_MESH_3_IGNORE_BOOST_PARAMETER_NAME_WARNINGS \ - CGAL_MESH_3_IGNORE_UNUSED_VARIABLES \ - CGAL_MESH_3_IGNORE_UNUSED_INTERNAL_DECLARATION - #endif // CGAL_MESH_3_CONFIG_H diff --git a/Mesh_3/include/CGAL/Mesh_3/experimental/Lipschitz_sizing_experimental.h b/Mesh_3/include/CGAL/Mesh_3/experimental/Lipschitz_sizing_experimental.h index bfae9e26801..828d6ec36ef 100644 --- a/Mesh_3/include/CGAL/Mesh_3/experimental/Lipschitz_sizing_experimental.h +++ b/Mesh_3/include/CGAL/Mesh_3/experimental/Lipschitz_sizing_experimental.h @@ -74,6 +74,7 @@ public: typedef typename CGAL::Default::Get::type Tree; typedef typename MeshDomain::Index Index; + typedef typename MeshDomain::Corner_index Corner_index; typedef typename MeshDomain::Subdomain_index Subdomain_index; typedef typename MeshDomain::Surface_patch_index Surface_patch_index; @@ -231,8 +232,8 @@ public: else if (dim == 0) { #ifdef CGAL_MESH_3_EXPERIMENTAL_USE_PATCHES_IDS - const Patches_ids& ids = - (m_domain.corners_incidences_map().find(p)->second); + const Corner_index cid = m_domain.corner_index(index); + const Patches_ids& ids = m_domain.corners_incidences_map().find(cid)->second; if (m_domain_is_a_box && ids.size() == 3) { diff --git a/Mesh_3/include/CGAL/Mesh_3/polylines_to_protect.h b/Mesh_3/include/CGAL/Mesh_3/polylines_to_protect.h index 1fc27924116..36fcf7d26a0 100644 --- a/Mesh_3/include/CGAL/Mesh_3/polylines_to_protect.h +++ b/Mesh_3/include/CGAL/Mesh_3/polylines_to_protect.h @@ -33,10 +33,10 @@ #include #include #include -#include // for - // CGAL::Null_subdomain_index +#include // for CGAL::Null_subdomain_index #include // for boost::prior #include +#include #include #include @@ -58,6 +58,201 @@ struct Returns_midpoint { = K().construct_midpoint_3_object(); return a < b ? midpt(a, b) : midpt(b, a); } + double operator()(const NT, + const NT) const + { + return 0.5; + } +}; + +template +struct Linear_interpolator { + typedef typename K::Point_3 Point_3; + + Point_3 interpolate(const Point_3& pa, + const Point_3& pb, + const NT a, + const NT b) const + { + return pa + (a / (a - b)) * ( pb - pa); + } + + + Point_3 operator()(const Point_3& pa, + const Point_3& pb, + const NT a, + const NT b) const + { + return + (a < b) ? + interpolate(pa, pb, a, b) : + interpolate(pb, pa, b, a); + } + double operator()(const NT a, + const NT b) const + { + return a / ( a - b ); + } +}; + + +class Isoline_equation { + double a; + double b; + double c; + double d; + +public: + Isoline_equation(double a, double b, double c, double d) + : a(a) + , b(b) + , c(c) + , d(d) + {} + + double y(double x) const { + return ( x*(a-b)-a ) / + ( c-a+x*(a-b-c+d) ); + // If (a+d) == (b+c), then the curve is a straight line. + } + double x(double y) const { + return ( y*(a-c)-a ) / + ( b-a+y*(a-b-c+d) ); + // If (a+d) == (b+c), then the curve is a straight line. + } +}; // end of class Isoline_equation + +template +class Insert_curve_in_graph { + typedef typename Geom_traits::Point_3 Point; + typedef typename Geom_traits::Vector_3 Vector; + + G_manip& g_manip; + const vertex_descriptor null_vertex; + const Geom_traits& gt; + const typename Geom_traits::Construct_translated_point_3 translate; + const typename Geom_traits::Construct_scaled_vector_3 scale; + const int prec; + const double max_squared_distance; + +public: + Insert_curve_in_graph(G_manip& g_manip, + const Geom_traits& gt, + const int prec = 10, + const double max_squared_distance = 0) + : g_manip(g_manip) + , null_vertex(g_manip.null_vertex()) + , gt(gt) + , translate(gt.construct_translated_point_3_object()) + , scale(gt.construct_scaled_vector_3_object()) + , prec(prec) + , max_squared_distance(max_squared_distance) + {} + + struct Coords { + Coords(double x, double y) : x(x), y(y) {} + double x; + double y; + }; + + void insert_curve(Isoline_equation equation, + vertex_descriptor start_v, + vertex_descriptor end_v, + Coords start, + Coords end, + Point p00, + Vector vx, + Vector vy) + { + if(CGAL::abs(start.x - end.x) >= CGAL::abs(start.y - end.y)) { + insert_curve(equation, &Isoline_equation::y, + start_v, end_v, + start.x, end.x, p00, vx, vy); + } else { + insert_curve(equation, &Isoline_equation::x, + start_v, end_v, + start.y, end.y, p00, vy, vx); + } + } +private: + void insert_curve(Isoline_equation equation, + double (Isoline_equation::* f)(double) const, + vertex_descriptor start_v, + vertex_descriptor end_v, + double start, + double end, + Point p00, + Vector vx, + Vector vy) + { +#ifdef CGAL_MESH_3_DEBUG_POLYLINES_TO_PROTECT + std::cerr << "New curve:\n"; +#endif // CGAL_MESH_3_DEBUG_POLYLINES_TO_PROTECT + const double step = (end - start)/prec; + const double stop = end-step/2; + const bool step_is_positive = (step > 0); + vertex_descriptor old = start_v; + vertex_descriptor v_int = null_vertex; + for(double x = start + step; + (step_is_positive ? x < stop : x > stop); + x += step) + { + const double y = (equation.*f)(x); +#ifdef CGAL_MESH_3_DEBUG_POLYLINES_TO_PROTECT + std::cerr << " (" << x << ", " << y << ")\n"; +#endif // CGAL_MESH_3_DEBUG_POLYLINES_TO_PROTECT + const Point inter_p = + translate(translate(p00, + scale(vx, x)), + scale(vy, y)); + v_int = g_manip.get_vertex(inter_p, false); + g_manip.try_add_edge(old, v_int); + +#ifndef CGAL_CFG_NO_CPP0X_LAMBDAS + CGAL_assertion_msg(max_squared_distance == 0 || + CGAL::squared_distance(g_manip.g[old].point, + g_manip.g[v_int].point) < + max_squared_distance, + ([this, old, v_int] { + std::stringstream s; + s << "Problem at segment (" + << this->g_manip.g[old].point << ", " + << this->g_manip.g[v_int].point << ")"; + return s.str(); + }().c_str())); +#else // no C++ lamdbas + CGAL_assertion(max_squared_distance == 0 || + CGAL::squared_distance(g_manip.g[old].point, + g_manip.g[v_int].point) < + max_squared_distance); +#endif // no C++ lamdbas + + old = v_int; + } + if(null_vertex != v_int) { + // v_int can be null if the curve is degenerated into one point. + g_manip.try_add_edge(v_int, end_v); +#ifndef CGAL_CFG_NO_CPP0X_LAMBDAS + CGAL_assertion_msg(max_squared_distance == 0 || + CGAL::squared_distance(g_manip.g[end_v].point, + g_manip.g[v_int].point) < + max_squared_distance, + ([this, end_v, v_int] { + std::stringstream s; + s << "Problem at segment (" + << this->g_manip.g[end_v].point << ", " + << this->g_manip.g[v_int].point << ")"; + return s.str(); + }().c_str())); +#else // no C++ lamdbas + CGAL_assertion(max_squared_distance == 0 || + CGAL::squared_distance(g_manip.g[end_v].point, + g_manip.g[v_int].point) < + max_squared_distance); +#endif // no C++ lamdbas + + } + } }; template }} // namespaces: end Mesh_3, end internal @@ -107,7 +303,7 @@ struct Polyline_visitor void add_node(typename boost::graph_traits::vertex_descriptor vd) { std::vector

& polyline = polylines.back(); - polyline.push_back(graph[vd]); + polyline.push_back(graph[vd].point); } void end_polyline() @@ -125,7 +321,7 @@ struct Angle_tester bool operator()(vertex_descriptor& v, const Graph& g) const { typedef typename boost::graph_traits::out_edge_iterator out_edge_iterator; - if (out_degree(v, g) != 2) + if (g[v].force_terminal || out_degree(v, g) != 2) return true; else { @@ -136,9 +332,9 @@ struct Angle_tester vertex_descriptor v2 = target(*out_edge_it++, g); CGAL_assertion(out_edge_it == out_edges_end); - const typename Kernel::Point_3& p = g[v]; - const typename Kernel::Point_3& p1 = g[v1]; - const typename Kernel::Point_3& p2 = g[v2]; + const typename Kernel::Point_3& p = g[v].point; + const typename Kernel::Point_3& p1 = g[v1].point; + const typename Kernel::Point_3& p2 = g[v2].point; if(CGAL::angle(p1, p, p2) == CGAL::ACUTE) { // const typename Kernel::Vector_3 e1 = p1 - p; @@ -192,11 +388,11 @@ void snap_graph_vertices(Graph& graph, BOOST_FOREACH(typename boost::graph_traits::vertex_descriptor v, vertices(graph)) { - const typename K::Point_3 p = graph[v]; + const typename K::Point_3 p = graph[v].point; NN_search nn(tree, p); CGAL_assertion(nn.begin() != nn.end()); if(squared_distance(nn.begin()->first, p) < sq_dist_bound) { - graph[v] = nn.begin()->first; + graph[v].point = nn.begin()->first; } } } @@ -214,10 +410,22 @@ struct Less_for_Graph_vertex_descriptors template bool operator()(vertex_descriptor v1, vertex_descriptor v2) const { - return graph[v1] < graph[v2]; + return graph[v1].point < graph[v2].point; } }; // end of Less_for_Graph_vertex_descriptors +namespace internal { +namespace polylines_to_protect_namespace { + template + struct Vertex_info { + Point point; + bool force_terminal; + Vertex_info() : force_terminal(false) {} + Vertex_info(const Point& p) : point(p), force_terminal(false) {} + }; +} // end namespace polylines_to_protect_namespace +} // end namespace internal + template void -polylines_to_protect(const CGAL::Image_3& cgal_image, - const double vx, const double vy, const double vz, - std::vector >& polylines, - Image_word_type*, - Null_subdomain_index null, - DomainFunctor domain_fct, - InterpolationFunctor interpolate, - PolylineInputIterator existing_polylines_begin, - PolylineInputIterator existing_polylines_end) +polylines_to_protect +(const CGAL::Image_3& cgal_image, + const double vx, const double vy, const double vz, + std::vector >& polylines, + Image_word_type*, + Null_subdomain_index null, + DomainFunctor domain_fct, + InterpolationFunctor interpolate, + PolylineInputIterator existing_polylines_begin, + PolylineInputIterator existing_polylines_end, + boost::optional scalar_interpolation_value = boost::none, + int prec = 10) { typedef typename DomainFunctor::result_type Domain_type; typedef typename Kernel_traits

::Kernel K; typedef P Point_3; - typedef boost::adjacency_list Graph; + + using CGAL::internal::polylines_to_protect_namespace::Vertex_info; + typedef boost::adjacency_list > Graph; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; // typedef typename boost::graph_traits::edge_iterator edge_iterator; const int xdim = static_cast(cgal_image.xdim()); const int ydim = static_cast(cgal_image.ydim()); const int zdim = static_cast(cgal_image.zdim()); - const int image_dims[3] = { xdim, ydim, zdim }; Graph graph; - internal::Mesh_3::Graph_manipulations g_manip(graph, interpolate); + + using namespace CGAL::internal::Mesh_3; + + typedef internal::Mesh_3::Graph_manipulations G_manip; + G_manip g_manip(graph, interpolate); + + const float& tx = cgal_image.image()->tx; + const float& ty = cgal_image.image()->ty; + const float& tz = cgal_image.image()->tz; + double max_squared_distance = + (std::max)( (std::max)(vx, vy), vz ); + max_squared_distance *= max_squared_distance; + max_squared_distance *= 2; + + typedef Insert_curve_in_graph Insert_c_in_g; + Insert_c_in_g insert_curve_in_graph(g_manip, K(), prec, + max_squared_distance); + typedef typename Insert_c_in_g::Coords Coords; std::size_t case4 = 0, // 4 colors @@ -269,6 +500,9 @@ polylines_to_protect(const CGAL::Image_3& cgal_image, for(int axis = 0; axis < 3; ++axis) { +#ifdef CGAL_MESH_3_DEBUG_POLYLINES_TO_PROTECT + std::cerr << "axis = " << axis << "\n"; +#endif // CGAL_MESH_3_DEBUG_POLYLINES_TO_PROTECT for(int i = 0; i < xdim; i+= (axis == 0 ? (std::max)(1, xdim-1) : 1 ) ) for(int j = 0; j < ydim; j+= (axis == 1 ? (std::max)(1, ydim-1) : 1 ) ) for(int k = 0; k < zdim; k+= (axis == 2 ? (std::max)(1, zdim-1) : 1 ) ) @@ -280,6 +514,9 @@ polylines_to_protect(const CGAL::Image_3& cgal_image, typedef array Pixel; +#ifdef CGAL_MESH_3_DEBUG_POLYLINES_TO_PROTECT + std::cerr << "Pixel(" << i << ", " << j << ", " << k << ")\n"; +#endif // CGAL_MESH_3_DEBUG_POLYLINES_TO_PROTECT Pixel pix00 = {{i , j , k }}, pix10 = pix00, pix01 = pix00, pix11 = pix00; @@ -291,6 +528,9 @@ polylines_to_protect(const CGAL::Image_3& cgal_image, ++pix01[axis_yy]; if(pix11[0] >= xdim || pix11[1] >= ydim || pix11[2] >= zdim) { // we have gone too far +#ifdef CGAL_MESH_3_DEBUG_POLYLINES_TO_PROTECT + std::cerr << " ... continue\n"; +#endif // CGAL_MESH_3_DEBUG_POLYLINES_TO_PROTECT continue; } typedef internal::Mesh_3::Enriched_pixel Enriched_pixel; array, 2> square = - {{ {{ { pix00, Point_3(), Domain_type(), 0 }, - { pix01, Point_3(), Domain_type(), 0 } }}, - {{ { pix10, Point_3(), Domain_type(), 0 }, - { pix11, Point_3(), Domain_type(), 0 } }} }}; + {{ {{ { pix00, Point_3(), Domain_type(), 0, false }, + { pix01, Point_3(), Domain_type(), 0, false } }}, + {{ { pix10, Point_3(), Domain_type(), 0, false }, + { pix11, Point_3(), Domain_type(), 0, false } }} }}; - std::map pixel_values_set; - for(int ii = 0; ii < 2; ++ii) - for(int jj = 0; jj < 2; ++jj) - { + std::map pixel_values_set; + for(int ii = 0; ii < 2; ++ii) { + for(int jj = 0; jj < 2; ++jj) { const Pixel& pixel = square[ii][jj].pixel; - double x = pixel[0] * vx; - double y = pixel[1] * vy; - double z = pixel[2] * vz; + double x = pixel[0] * vx + tx; + double y = pixel[1] * vy + ty; + double z = pixel[2] * vz + tz; + square[ii][jj].on_edge_of_the_cube = + ( ( ( 0 == pixel[0] || (xdim - 1) == pixel[0] ) ? 1 : 0 ) + + + ( ( 0 == pixel[1] || (ydim - 1) == pixel[1] ) ? 1 : 0 ) + + + ( ( 0 == pixel[2] || (zdim - 1) == pixel[2] ) ? 1 : 0 ) > 1 ); +#ifdef CGAL_MESH_3_DEBUG_POLYLINES_TO_PROTECT + if(square[ii][jj].on_edge_of_the_cube) { + std::cerr << " Pixel(" << pixel[0] << ", " << pixel[1] << ", " + << pixel[2] << ") is on edge\n"; + } +#endif // CGAL_MESH_3_DEBUG_POLYLINES_TO_PROTECT + square[ii][jj].point = Point_3(x, y, z); square[ii][jj].word = - static_cast(cgal_image.value(pixel[0], - pixel[1], - pixel[2])); + CGAL::IMAGEIO::static_evaluate + (cgal_image.image(), + pixel[0], + pixel[1], + pixel[2]); square[ii][jj].domain = domain_fct(square[ii][jj].word); + if(scalar_interpolation_value != boost::none) { + square[ii][jj].word = + Image_word_type(square[ii][jj].word - + (*scalar_interpolation_value)); + } ++pixel_values_set[square[ii][jj].domain]; } + } + const Point_3& p00 = square[0][0].point; const Point_3& p10 = square[1][0].point; const Point_3& p01 = square[0][1].point; @@ -331,38 +592,45 @@ polylines_to_protect(const CGAL::Image_3& cgal_image, const Image_word_type& v01 = square[0][1].word; const Image_word_type& v11 = square[1][1].word; - bool out00 = null(square[0][0].domain); - bool out10 = null(square[1][0].domain); - bool out01 = null(square[0][1].domain); - bool out11 = null(square[1][1].domain); + { + bool out00 = null(square[0][0].domain); + bool out10 = null(square[1][0].domain); + bool out01 = null(square[0][1].domain); + bool out11 = null(square[1][1].domain); - // - // Protect the edges of the cube - // - if(pix00[axis_xx] == 0 && - ! ( out00 && out01 ) ) - { - g_manip.try_add_edge(g_manip.get_vertex(p00), - g_manip.get_vertex(p01)); - } - if(pix11[axis_xx] == image_dims[axis_xx]-1 && - ! ( out10 && out11 ) ) - { - g_manip.try_add_edge(g_manip.get_vertex(p10), - g_manip.get_vertex(p11)); - } - if(pix00[axis_yy] == 0 && - ! ( out00 && out10 ) ) - { - g_manip.try_add_edge(g_manip.get_vertex(p00), - g_manip.get_vertex(p10)); - } - if(pix11[axis_yy] == image_dims[axis_yy]-1 && - ! ( out01 && out11 ) ) - { - g_manip.try_add_edge(g_manip.get_vertex(p01), - g_manip.get_vertex(p11)); - } + bool on_edge00 = square[0][0].on_edge_of_the_cube; + bool on_edge10 = square[1][0].on_edge_of_the_cube; + bool on_edge01 = square[0][1].on_edge_of_the_cube; + bool on_edge11 = square[1][1].on_edge_of_the_cube; + + // + // Protect the edges of the cube + // + if(pix00[axis_xx] == 0 && + ! ( out00 && out01 ) ) + { + g_manip.try_add_edge(g_manip.get_vertex(p00, on_edge00), + g_manip.get_vertex(p01, on_edge01)); + } + if(pix11[axis_xx] == image_dims[axis_xx]-1 && + ! ( out10 && out11 ) ) + { + g_manip.try_add_edge(g_manip.get_vertex(p10, on_edge10), + g_manip.get_vertex(p11, on_edge11)); + } + if(pix00[axis_yy] == 0 && + ! ( out00 && out10 ) ) + { + g_manip.try_add_edge(g_manip.get_vertex(p00, on_edge00), + g_manip.get_vertex(p10, on_edge10)); + } + if(pix11[axis_yy] == image_dims[axis_yy]-1 && + ! ( out01 && out11 ) ) + { + g_manip.try_add_edge(g_manip.get_vertex(p01, on_edge01), + g_manip.get_vertex(p11, on_edge11)); + } + } // end of scope for outIJ and on_edgeIJ // // Protect lines inside the square @@ -375,6 +643,7 @@ polylines_to_protect(const CGAL::Image_3& cgal_image, CGAL_assertion(square[1][0].domain != square[1][1].domain); CGAL_assertion(square[0][1].domain != square[1][1].domain); CGAL_assertion(square[0][1].domain != square[1][0].domain); + case_4: // case 4 or case 2-2 // @@ -388,12 +657,20 @@ case_4: // --------------- // ++case4; - vertex_descriptor left = g_manip.split(p00, p01, v00, v01, out00, out01); - vertex_descriptor right = g_manip.split(p10, p11, v10, v11, out10, out11); - vertex_descriptor top = g_manip.split(p01, p11, v01, v11, out01, out11); - vertex_descriptor bottom = g_manip.split(p00, p10, v00, v10, out00, out10); + vertex_descriptor left = g_manip.split(square[0][0], + square[0][1], null); + vertex_descriptor right = g_manip.split(square[1][0], + square[1][1], null); + vertex_descriptor top = g_manip.split(square[0][1], + square[1][1], null); + vertex_descriptor bottom = g_manip.split(square[0][0], + square[1][0], null); - vertex_descriptor vmid = g_manip.get_vertex(midpoint(p00, p11)); + vertex_descriptor vmid = g_manip.split(graph[left].point, + graph[right].point, + v00, v10, + false, false, + false, false); g_manip.try_add_edge(left , vmid); g_manip.try_add_edge(right , vmid); g_manip.try_add_edge(top , vmid); @@ -404,8 +681,7 @@ case_4: if(square[0][0].domain == square[1][1].domain) { // Diagonal, but the wrong one. // Vertical swap - std::swap(square[0][1], square[0][0]); std::swap(out01, out00); - std::swap(square[1][1], square[1][0]); std::swap(out11, out10); + std::swap(square[0][1], square[0][0]); } if(square[0][1].domain == square[1][0].domain) { // diagonal case 1-2-1 @@ -432,57 +708,60 @@ case_4: CGAL_assertion(square[1][1].domain != square[0][0].domain); CGAL_assertion(square[0][1].domain != square[0][0].domain); CGAL_assertion(square[0][1].domain != square[1][1].domain); +case_1_2_1: ++case121; - vertex_descriptor left = g_manip.split(p00, p01, v00, v01, out00, out01); - vertex_descriptor right = g_manip.split(p10, p11, v10, v11, out10, out11); - vertex_descriptor top = g_manip.split(p01, p11, v01, v11, out01, out11); - vertex_descriptor bottom = g_manip.split(p00, p10, v00, v10, out00, out10); + vertex_descriptor left = g_manip.split(square[0][0], + square[0][1], null); + vertex_descriptor right = g_manip.split(square[1][0], + square[1][1], null); + vertex_descriptor top = g_manip.split(square[0][1], + square[1][1], null); + vertex_descriptor bottom = g_manip.split(square[0][0], + square[1][0], null); - vertex_descriptor old_left = left; - vertex_descriptor old_right = right; - vertex_descriptor v_int_left, v_int_right; - - // approximate the arcs by 10 segments - // -> 9 intermediate vertices - for(double x = 0.05; x < 0.5; x+= 0.05) - { - const Point_3 inter_left = - translate(p00 - , x * vector(p00, p10) // x - + ((1.-2.*x)/(2.-3.*x)) * vector(p00, p01)); // y - const Point_3 inter_right = - translate(p11 - , x * vector(p11, p01) // x - + ((1.-2.*x)/(2.-3.*x)) * vector(p11, p10)); // y - v_int_left = g_manip.get_vertex(inter_left); - v_int_right = g_manip.get_vertex(inter_right); - g_manip.try_add_edge(old_left, v_int_left); - g_manip.try_add_edge(old_right, v_int_right); - old_left = v_int_left; - old_right = v_int_right; + Isoline_equation equation = + (scalar_interpolation_value == boost::none) ? + Isoline_equation(1, -1, -1, 0) : + Isoline_equation(v00, v10, v01, v11); + insert_curve_in_graph.insert_curve(equation, + left, bottom, + Coords(0., interpolate(v00, v01) ), + Coords(interpolate(v00, v10), 0. ), + p00, + p10 - p00, + p01 - p00); + if(scalar_interpolation_value == boost::none) { + equation = Isoline_equation(0, -1, -1, 1); } - g_manip.try_add_edge(v_int_left, bottom); - g_manip.try_add_edge(v_int_right, top); + insert_curve_in_graph.insert_curve(equation, + top, right, + Coords(interpolate(v01, v11), 1. ), + Coords(1., interpolate(v10, v11) ), + p00, + p10 - p00, + p01 - p00); } else { // case 2-1-1 if(square[0][0].domain == square[1][0].domain) { // Diagonal swap - std::swap(square[0][1], square[1][0]); std::swap(out01, out10); + std::swap(square[0][1], square[1][0]); } else if(square[0][1].domain == square[1][1].domain) { // The other diagonal swap - std::swap(square[0][0], square[1][1]); std::swap(out00, out11); + std::swap(square[0][0], square[1][1]); } else if(square[1][0].domain == square[1][1].domain) { // Vertical swap - std::swap(square[0][0], square[1][0]); std::swap(out00, out10); - std::swap(square[0][1], square[1][1]); std::swap(out01, out11); + std::swap(square[0][0], square[1][0]); + std::swap(square[0][1], square[1][1]); } CGAL_assertion(square[0][0].domain == square[0][1].domain); CGAL_assertion(square[0][0].domain != square[1][0].domain); CGAL_assertion(square[0][0].domain != square[1][1].domain); CGAL_assertion(square[1][0].domain != square[1][1].domain); ++case211; + // Note: this case cannot occur with non-segmented scalar + // images, because it needs three domains. // // A-------------B // | | | @@ -509,37 +788,28 @@ case_4: Point_3 midright = midpoint(p10, p11); Point_3 inter = translate(midleft , (2./3) * vector(midleft, midright)); - vertex_descriptor v_inter = g_manip.get_vertex(inter); - vertex_descriptor right = g_manip.split(p10, p11, v10, v11, out10, out11); - vertex_descriptor top = g_manip.split(p01, p11, v01, v11, out01, out11); - vertex_descriptor bottom = g_manip.split(p00, p10, v00, v10, out00, out10); + vertex_descriptor v_inter = g_manip.get_vertex(inter, false); + vertex_descriptor right = g_manip.split(square[1][0], + square[1][1], null); + vertex_descriptor top = g_manip.split(square[0][1], + square[1][1], null); + vertex_descriptor bottom = g_manip.split(square[0][0], + square[1][0], null); - vertex_descriptor old_top = top; - vertex_descriptor old_bottom = bottom; - vertex_descriptor v_int_top, v_int_bottom; - - // approximate the arcs by 10 segments - // -> 9 intermediate vertices - for(double x = 0.51666; x < 0.66; x+= 0.016666) - { - const Point_3 inter_top = - translate(p00 - , x * vector(p00, p10) // x - + ((1./x) - 1.) * vector(p00, p01)); // y - const Point_3 inter_bottom = - translate(p00 - , x * vector(p00, p10) // x - + (2.-(1./x)) * vector(p00, p01)); // y - v_int_top = g_manip.get_vertex(inter_top); - v_int_bottom = g_manip.get_vertex(inter_bottom); - g_manip.try_add_edge(old_top, v_int_top); - g_manip.try_add_edge(old_bottom, v_int_bottom); - old_top = v_int_top; - old_bottom = v_int_bottom; - } - - g_manip.try_add_edge(v_int_bottom, v_inter); - g_manip.try_add_edge(v_int_top, v_inter); + insert_curve_in_graph.insert_curve(Isoline_equation(1, -1, 1, 0), + bottom, v_inter, + Coords( 0.5 , 0. ), + Coords( 2./3., 0.5 ), + p00, + p10 - p00, + p01 - p00); + insert_curve_in_graph.insert_curve(Isoline_equation(1, 0, 1, -1), + top, v_inter, + Coords( 0.5 , 1. ), + Coords( 2./3., 0.5 ), + p00, + p10 - p00, + p01 - p00); g_manip.try_add_edge(right, v_inter); } // end case 2-1-1 } // end `case 3:` @@ -552,18 +822,18 @@ case_4: if(square[0][0].domain==square[1][0].domain) { // case 2-2, diagonal swap - std::swap(square[0][1], square[1][0]); std::swap(out01, out10); + std::swap(square[0][1], square[1][0]); CGAL_assertion(square[0][0].domain==square[0][1].domain); } if(square[1][0].domain==square[1][1].domain) { // case 2-2, vertical swap - std::swap(square[0][1], square[1][1]); std::swap(out01, out11); - std::swap(square[0][0], square[1][0]); std::swap(out00, out10); + std::swap(square[0][1], square[1][1]); + std::swap(square[0][0], square[1][0]); CGAL_assertion(square[0][0].domain==square[0][1].domain); } if(square[0][1].domain==square[1][1].domain) { // case 2-2, diagonal swap - std::swap(square[0][0], square[1][1]); std::swap(out00, out11); + std::swap(square[0][0], square[1][1]); CGAL_assertion(square[0][0].domain==square[0][1].domain); } @@ -583,21 +853,56 @@ case_4: // CGAL_assertion(square[1][0].domain==square[1][1].domain); CGAL_assertion(square[1][0].domain!=square[0][1].domain); - vertex_descriptor top = g_manip.split(p01, p11, v01, v11, out01, out11); - vertex_descriptor bottom = g_manip.split(p00, p10, v00, v10, out00, out10); - g_manip.try_add_edge(top, bottom); + vertex_descriptor top = g_manip.split(square[0][1], + square[1][1], null); + vertex_descriptor bottom = g_manip.split(square[0][0], + square[1][0], null); + if(scalar_interpolation_value == boost::none) { + g_manip.try_add_edge(top, bottom); + } else { + insert_curve_in_graph.insert_curve(Isoline_equation(v00, v10, + v01, v11), + top, bottom, + Coords(interpolate(v01,v11), 1.), + Coords(interpolate(v00,v10), 0.), + p00, + p10 - p00, + p01 - p00); + } } else { // Else diagonal case case 2-2 // Same as the case with 4 colors CGAL_assertion(square[0][0].domain==square[1][1].domain); CGAL_assertion(square[1][0].domain==square[0][1].domain); CGAL_assertion(square[0][0].domain!=square[0][1].domain); + + if(scalar_interpolation_value != boost::none) { + // Compute the squared distance between the two branches of + // the hyperbola. + const double discrimant = double(v00) * v11 - double(v01) * v10; + const double squared_distance = + 8 * CGAL::abs(discrimant) / CGAL::square(double(v00) - v10 - v01 + v11); +#ifdef CGAL_MESH_3_DEBUG_POLYLINES_TO_PROTECT + std::cerr << "squared_distance: " << squared_distance << "\n"; +#endif // CGAL_MESH_3_DEBUG_POLYLINES_TO_PROTECT + if(CGAL::square(prec) * squared_distance > 1) + { + // In that case, the case 1-2-1 will be applied + if(discrimant > 0.) { + // Vertical swap + std::swap(square[0][1], square[0][0]); + std::swap(square[1][1], square[1][0]); + } + goto case_1_2_1; + } + } // scalar interpolation + goto case_4; } } else { // case of two colors with one pixel green and three red - Image_word_type value_alone; + Domain_type value_alone; if(pixel_values_set.begin()->second == 1) { value_alone = pixel_values_set.begin()->first; } else { @@ -607,20 +912,20 @@ case_4: } if(square[0][1].domain == value_alone) { // central symmetry - std::swap(square[0][1], square[1][0]); std::swap(out01, out10); - std::swap(square[0][0], square[1][1]); std::swap(out00, out11); + std::swap(square[0][1], square[1][0]); + std::swap(square[0][0], square[1][1]); CGAL_assertion(square[1][0].domain == value_alone); } if(square[1][1].domain == value_alone) { // vertical swap - std::swap(square[0][0], square[0][1]); std::swap(out00, out01); - std::swap(square[1][0], square[1][1]); std::swap(out10, out11); + std::swap(square[0][0], square[0][1]); + std::swap(square[1][0], square[1][1]); CGAL_assertion(square[1][0].domain == value_alone); } if(square[0][0].domain == value_alone) { // horizontal swap - std::swap(square[0][1], square[1][1]); std::swap(out01, out11); - std::swap(square[0][0], square[1][0]); std::swap(out00, out10); + std::swap(square[0][1], square[1][1]); + std::swap(square[0][0], square[1][0]); CGAL_assertion(square[1][0].domain == value_alone); } ++case31; @@ -638,23 +943,23 @@ case_4: CGAL_assertion(square[1][0].domain != square[0][0].domain); CGAL_assertion(square[1][1].domain == square[0][0].domain); CGAL_assertion(square[0][1].domain == square[0][0].domain); - vertex_descriptor bottom = g_manip.split(p00, p10, v00, v10, out00, out10); - vertex_descriptor old = bottom; + vertex_descriptor bottom = g_manip.split(square[0][0], + square[1][0], null); + vertex_descriptor right = g_manip.split(square[1][0], + square[1][1], null); - vertex_descriptor v_int; - for(double x = 0.55; x < 1.; x+= 0.05) - { - const Point_3 inter = - translate(p00 - , x * vector(p00, p10) // x - + (1.-1./(2.*x)) * vector(p00, p01)); // y - v_int = g_manip.get_vertex(inter); - g_manip.try_add_edge(old, v_int); - old = v_int; - } + Isoline_equation equation = + (scalar_interpolation_value == boost::none) ? + Isoline_equation(1, -1, 1, 1) : + Isoline_equation(v00, v10, v01, v11); - vertex_descriptor right = g_manip.split(p10, p11, v10, v11, out10, out11); - g_manip.try_add_edge(v_int, right); + insert_curve_in_graph.insert_curve(equation, + bottom, right, + Coords(interpolate(v00, v10), 0. ), + Coords(1., interpolate(v10, v11) ), + p00, + p10 - p00, + p01 - p00); } } break; @@ -706,7 +1011,9 @@ polylines_to_protect(std::vector >& polylines, { typedef P Point_3; typedef typename Kernel_traits

::Kernel K; - typedef boost::adjacency_list Graph; + using CGAL::internal::polylines_to_protect_namespace::Vertex_info; + typedef boost::adjacency_list > Graph; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; typedef typename std::iterator_traits::value_type Polyline; @@ -727,8 +1034,8 @@ polylines_to_protect(std::vector >& polylines, typename Polyline::iterator pit = polyline.begin(); while (boost::next(pit) != polyline.end()) { - vertex_descriptor v = g_manip.get_vertex(*pit); - vertex_descriptor w = g_manip.get_vertex(*boost::next(pit)); + vertex_descriptor v = g_manip.get_vertex(*pit, false); + vertex_descriptor w = g_manip.get_vertex(*boost::next(pit), false); g_manip.try_add_edge(v, w); ++pit; } diff --git a/Mesh_3/include/CGAL/Mesh_3/utilities.h b/Mesh_3/include/CGAL/Mesh_3/utilities.h index 2080c3b0fea..d0c1d4825e0 100644 --- a/Mesh_3/include/CGAL/Mesh_3/utilities.h +++ b/Mesh_3/include/CGAL/Mesh_3/utilities.h @@ -70,9 +70,9 @@ struct Debug_messages_tools { */ template struct First_of : - public CGAL::unary_function + public CGAL::cpp98::unary_function { - typedef CGAL::unary_function Base; + typedef CGAL::cpp98::unary_function Base; typedef typename Base::result_type result_type; typedef typename Base::argument_type argument_type; diff --git a/Mesh_3/include/CGAL/Mesh_criteria_3.h b/Mesh_3/include/CGAL/Mesh_criteria_3.h index 2360fb78a3c..57854afdeb5 100644 --- a/Mesh_3/include/CGAL/Mesh_criteria_3.h +++ b/Mesh_3/include/CGAL/Mesh_criteria_3.h @@ -33,7 +33,8 @@ #include #include -#include +#include +#include #include #include #include @@ -45,8 +46,8 @@ namespace parameters { // see CGAL_PRAGMA_DIAG_PUSH -// see -CGAL_MESH_3_IGNORE_BOOST_PARAMETER_NAME_WARNINGS +// see +CGAL_IGNORE_BOOST_PARAMETER_NAME_WARNINGS BOOST_PARAMETER_NAME( (edge_size, tag) edge_size_ ) BOOST_PARAMETER_NAME( (edge_sizing_field, tag) edge_sizing_field_ ) diff --git a/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h b/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h index 839718ce1e3..4b7da73de33 100644 --- a/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h +++ b/Mesh_3/include/CGAL/Mesh_domain_with_polyline_features_3.h @@ -47,6 +47,10 @@ #include // for boost::prior and boost::next #include #include +#include +#include +#include +#include namespace CGAL { @@ -538,6 +542,7 @@ template < typename MeshDomain_3 > class Mesh_domain_with_polyline_features_3 : public MeshDomain_3 { + typedef Mesh_domain_with_polyline_features_3 Self; public: /// \name Types /// @{ @@ -563,24 +568,11 @@ public: typedef typename MeshDomain_3::Point_3 Point_3; #endif // DOXYGEN_RUNNING -#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES /// \name Creation +/// Constructors. Forwards the arguments to the constructor +/// of the base class. /// @{ -/*! -Constructor. Forwards the arguments to the constructor -of the base class. -*/ - template - Mesh_domain_with_polyline_features_3(const T& ...t) - : MeshDomain_3(t...) - , current_corner_index_(1) - , current_curve_index_(1) - , curves_aabb_tree_is_built(false) {} -/// @} -#else - /// Constructors - /// Call the base class constructor Mesh_domain_with_polyline_features_3() : MeshDomain_3() , current_corner_index_(1) @@ -588,12 +580,25 @@ of the base class. , curves_aabb_tree_is_built(false) {} template - Mesh_domain_with_polyline_features_3(const T1& o1) + Mesh_domain_with_polyline_features_3 + (const T1& o1, typename boost::disable_if, + CGAL::Tag_false>::type* = 0) : MeshDomain_3(o1) , current_corner_index_(1) , current_curve_index_(1) , curves_aabb_tree_is_built(false) {} +#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + template + Mesh_domain_with_polyline_features_3(const T1& o1, const T2& o2, const T& ...o) + : MeshDomain_3(o1, o2, o...) + , current_corner_index_(1) + , current_curve_index_(1) + , curves_aabb_tree_is_built(false) {} +/// @} +#else + /// Constructors + /// Call the base class constructor template Mesh_domain_with_polyline_features_3(const T1& o1, const T2& o2) : MeshDomain_3(o1, o2) @@ -623,6 +628,28 @@ of the base class. /// @cond DEVELOPERS /// @{ + + /// Add a 0-dimensional feature in the domain. + Corner_index add_corner(const Point_3& p); + + /// Overloads where the last parameter \c out is not `CGAL::Emptyset_iterator()`. + template + IndicesOutputIterator + add_corners(InputIterator first, InputIterator end, + IndicesOutputIterator out /*= CGAL::Emptyset_iterator()*/); + + /*! + Add 0-dimensional features in the domain. The value type of `InputIterator` must + be `Point_3`. + */ + template + void + add_corners(InputIterator first, InputIterator end) + { add_corners(first, end, CGAL::Emptyset_iterator()); } + + Corner_index register_corner(const Point_3& p, const Curve_index& index); + Corner_index add_corner_with_context(const Point_3& p, const Surface_patch_index& index); + /// Overloads where the last parameter \c out is not /// `CGAL::Emptyset_iterator()`. template @@ -808,7 +835,6 @@ of the base class. Curve_index insert_edge(InputIterator first, InputIterator end); /// @endcond private: - void register_corner(const Point_3& p, const Curve_index& index); void compute_corners_incidences(); /// Returns Index associated to p (p must be the coordinates of a corner @@ -843,21 +869,18 @@ private: public: /// @cond DEVELOPERS typedef CGAL::AABB_tree Curves_AABB_tree; - typedef std::set Set_of_patch_ids; - typedef std::map Corners_incidence_map; private: - Corners_incidence_map corners_incidence_map_; - mutable Curves_AABB_tree curves_aabb_tree_; + mutable boost::shared_ptr curves_aabb_tree_ptr_; mutable bool curves_aabb_tree_is_built; public: - const Corners_incidence_map& corners_incidences_map() const - { return corners_incidence_map_; } + const Corners_incidences& corners_incidences_map() const + { return corners_incidences_; } const Curves_AABB_tree& curves_aabb_tree() const { if(!curves_aabb_tree_is_built) build_curves_aabb_tree(); - return curves_aabb_tree_; + return *curves_aabb_tree_ptr_; } Curve_index maximal_curve_index() const { if(edges_incidences_.empty()) return Curve_index(); @@ -870,7 +893,11 @@ public: CGAL::Real_timer timer; timer.start(); #endif - curves_aabb_tree_.clear(); + if(curves_aabb_tree_ptr_) { + curves_aabb_tree_ptr_->clear(); + } else { + curves_aabb_tree_ptr_ = boost::make_shared(); + } for(typename Edges::const_iterator edges_it = edges_.begin(), edges_end = edges_.end(); @@ -882,10 +909,10 @@ public: end = polyline.points_.end() - 1; pit != end; ++pit) { - curves_aabb_tree_.insert(std::make_pair(edges_it, pit)); + curves_aabb_tree_ptr_->insert(std::make_pair(edges_it, pit)); } } - curves_aabb_tree_.build(); + curves_aabb_tree_ptr_->build(); curves_aabb_tree_is_built = true; #if CGAL_MESH_3_VERBOSE timer.stop(); @@ -893,12 +920,6 @@ public: #endif } // end build_curves_aabb_tree() /// @endcond -private: - // Disabled copy constructor & assignment operator - typedef Mesh_domain_with_polyline_features_3 Self; - Mesh_domain_with_polyline_features_3(const Self& src); - Self& operator=(const Self& src); - }; // end class Mesh_domain_with_polyline_features_3 @@ -1013,6 +1034,67 @@ construct_point_on_curve(const Point_3& starting_point, } +/// @cond DEVELOPERS +template +typename Mesh_domain_with_polyline_features_3::Corner_index +Mesh_domain_with_polyline_features_3:: +add_corner(const Point_3& p) +{ + typename Corners::iterator cit = corners_.lower_bound(p); + + // If the corner already exists, return its assigned Corner_index... + if(cit != corners_.end() && !(corners_.key_comp()(p, cit->first))) + return cit->second; + + // ... otherwise, insert it! + const Corner_index index = current_corner_index_++; + corners_.insert(cit, std::make_pair(p, index)); + + return index; +} + + +template +template +IndicesOutputIterator +Mesh_domain_with_polyline_features_3:: +add_corners(InputIterator first, InputIterator end, + IndicesOutputIterator indices_out) +{ + while ( first != end ) + *indices_out++ = add_corner(*first++); + + return indices_out; +} + +template +typename Mesh_domain_with_polyline_features_3::Corner_index +Mesh_domain_with_polyline_features_3:: +register_corner(const Point_3& p, const Curve_index& curve_index) +{ + // 'add_corner' will itself seek if 'p' is already a corner, and, in that case, + // return the Corner_index that has been assigned to this position. + Corner_index index = add_corner(p); + corners_tmp_incidences_[index].insert(curve_index); + + return index; +} + + +template +typename Mesh_domain_with_polyline_features_3::Corner_index +Mesh_domain_with_polyline_features_3:: +add_corner_with_context(const Point_3& p, const Surface_patch_index& surface_patch_index) +{ + Corner_index index = add_corner(p); + + Surface_patch_index_set& incidences = corners_incidences_[index]; + incidences.insert(surface_patch_index); + + return index; +} +/// @endcond + template template @@ -1080,21 +1162,12 @@ add_features_and_incidences(InputIterator first, InputIterator end, polyline = get(polyline_pmap, *first); const typename boost::property_traits::reference patches_ids = get(inc_patches_ind_pmap, *first); - const typename Gt::Point_3& p1 = *polyline.begin(); - const typename Gt::Point_3& p2 = *boost::prior(polyline.end()); - Set_of_patch_ids& ids_p1 = corners_incidence_map_[p1]; - std::copy(patches_ids.begin(), - patches_ids.end(), - std::inserter(ids_p1, ids_p1.begin())); - Set_of_patch_ids& ids_p2 = corners_incidence_map_[p2]; - std::copy(patches_ids.begin(), - patches_ids.end(), - std::inserter(ids_p2, ids_p2.begin())); - Curve_index curve_id = - insert_edge(polyline.begin(), polyline.end()); + + Curve_index curve_id = insert_edge(polyline.begin(), polyline.end()); edges_incidences_[curve_id].insert(patches_ids.begin(), patches_ids.end()); *indices_out++ = curve_id; } + compute_corners_incidences(); return indices_out; } @@ -1172,7 +1245,8 @@ get_incidences(Curve_index id, { typename Edges_incidences::const_iterator it = edges_incidences_.find(id); - if(it == edges_incidences_.end()) return indices_out; + if(it == edges_incidences_.end()) + return indices_out; const Surface_patch_index_set& incidences = it->second; @@ -1187,6 +1261,9 @@ get_corner_incidences(Corner_index id, IndicesOutputIterator indices_out) const { typename Corners_incidences::const_iterator it = corners_incidences_.find(id); + if(it == corners_incidences_.end()) + return indices_out; + const Surface_patch_index_set& incidences = it->second; return std::copy(incidences.begin(), incidences.end(), indices_out); } @@ -1198,8 +1275,10 @@ Mesh_domain_with_polyline_features_3:: get_corner_incident_curves(Corner_index id, IndicesOutputIterator indices_out) const { - typename Corners_tmp_incidences::const_iterator it = - corners_tmp_incidences_.find(id); + typename Corners_tmp_incidences::const_iterator it = corners_tmp_incidences_.find(id); + if(it == corners_tmp_incidences_.end()) + return indices_out; + const std::set& incidences = it->second; return std::copy(incidences.begin(), incidences.end(), indices_out); } @@ -1323,7 +1402,6 @@ compute_corners_incidences() } Surface_patch_index_set& incidences = corners_incidences_[id]; - // That should be an empty set. BOOST_FOREACH(Curve_index curve_index, corner_tmp_incidences) { @@ -1347,34 +1425,11 @@ Mesh_domain_with_polyline_features_3:: get_incidences(Curve_index id) const { typename Edges_incidences::const_iterator it = edges_incidences_.find(id); + CGAL_assertion(it != edges_incidences_.end()); + return it->second; } -/// @endcond -template -void -Mesh_domain_with_polyline_features_3:: -register_corner(const Point_3& p, const Curve_index& curve_index) -{ - - typename Corners::iterator cit = corners_.lower_bound(p); - - // If the corner already exists, returns... - if(cit != corners_.end() && !(corners_.key_comp()(p, cit->first))) { - corners_tmp_incidences_[cit->second].insert(curve_index); - return; - } - - // ...else insert it! - - const Corner_index index = current_corner_index_; - ++current_corner_index_; - - corners_.insert(cit, std::make_pair(p, index)); - corners_tmp_incidences_[index].insert(curve_index); -} - -/// @cond DEVELOPERS template template typename Mesh_domain_with_polyline_features_3::Curve_index diff --git a/Mesh_3/include/CGAL/Polyhedral_complex_mesh_domain_3.h b/Mesh_3/include/CGAL/Polyhedral_complex_mesh_domain_3.h index 13464bb3317..600de3aeb0c 100644 --- a/Mesh_3/include/CGAL/Polyhedral_complex_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Polyhedral_complex_mesh_domain_3.h @@ -47,7 +47,7 @@ #include #include #include - +#include #include #include @@ -57,156 +57,6 @@ namespace CGAL { -/// @cond DEVELOPERS -namespace internal { -namespace Mesh_3 { - -template -void dump_graph_edges(std::ostream& out, const Graph& g) -{ - typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; - typedef typename boost::graph_traits::edge_descriptor edge_descriptor; - - out.precision(17); - BOOST_FOREACH(edge_descriptor e, edges(g)) - { - vertex_descriptor s = source(e, g); - vertex_descriptor t = target(e, g); - out << "2 " << g[s] << " " << g[t] << "\n"; - } -} - -template -void dump_graph_edges(const char* filename, const Graph& g) -{ - std::ofstream out(filename); - dump_graph_edges(out, g); -} - -template -struct Angle_tester -{ - template - bool operator()(vertex_descriptor& v, const Graph& g) const - { - typedef typename boost::graph_traits::out_edge_iterator out_edge_iterator; - if (out_degree(v, g) != 2) - return true; - else - { - out_edge_iterator out_edge_it, out_edges_end; - boost::tie(out_edge_it, out_edges_end) = out_edges(v, g); - - vertex_descriptor v1 = target(*out_edge_it++, g); - vertex_descriptor v2 = target(*out_edge_it++, g); - CGAL_assertion(out_edge_it == out_edges_end); - - const typename Kernel::Point_3& p = g[v]; - const typename Kernel::Point_3& p1 = g[v1]; - const typename Kernel::Point_3& p2 = g[v2]; - - return (CGAL::angle(p1, p, p2) == CGAL::ACUTE); - } - } -}; - -template -struct Is_featured_edge { - const Polyhedron* polyhedron; - typename boost::property_map::type eifm; - Is_featured_edge() - : polyhedron(0) - {} // required by boost::filtered_graph - - Is_featured_edge(const Polyhedron& polyhedron) - : polyhedron(&polyhedron), eifm(get(edge_is_feature,polyhedron)) - {} - - bool operator()(typename boost::graph_traits::edge_descriptor e) const { - return get(eifm, e); - } -}; // end Is_featured_edge - -template -struct Is_border_edge { - const Polyhedron* polyhedron; - Is_border_edge() : polyhedron(0) {} // required by boost::filtered_graph - Is_border_edge(const Polyhedron& polyhedron) : polyhedron(&polyhedron) {} - - bool operator()(typename boost::graph_traits::edge_descriptor e) const { - return is_border(halfedge(e, *polyhedron), *polyhedron) || - is_border(opposite(halfedge(e, *polyhedron), *polyhedron), *polyhedron); - } -}; // end Is_featured_edge - -template -struct Extract_polyline_with_context_visitor -{ - typedef typename Polyhedral_mesh_domain::Polyhedron_type Polyhedron; - std::vector& polylines; - const Graph& graph; - - Extract_polyline_with_context_visitor - (const Graph& graph, - typename std::vector& polylines) - : polylines(polylines), graph(graph) - {} - - void start_new_polyline() - { - polylines.push_back(Polyline_with_context()); - } - - void add_node(typename boost::graph_traits::vertex_descriptor vd) - { - if(polylines.back().polyline_content.empty()) { - polylines.back().polyline_content.push_back(graph[vd]); - } - } - - void add_edge(typename boost::graph_traits::edge_descriptor ed) - { - typename boost::graph_traits::vertex_descriptor - s = source(ed, graph), - t = target(ed, graph); - Polyline_with_context& polyline = polylines.back(); - CGAL_assertion(!polyline.polyline_content.empty()); - if(polyline.polyline_content.back() != graph[s]) { - polyline.polyline_content.push_back(graph[s]); - } else if(polyline.polyline_content.back() != graph[t]) { - // if the edge is zero-length, it is ignored - polyline.polyline_content.push_back(graph[t]); - } - const typename boost::edge_bundle_type::type & - set_of_indices = graph[ed]; - polyline.context.adjacent_patches_ids.insert(set_of_indices.begin(), - set_of_indices.end()); - } - - void end_polyline() - { - // ignore degenerated polylines - if(polylines.back().polyline_content.size() < 2) - polylines.resize(polylines.size() - 1); - // else { - // std::cerr << "Polyline with " << polylines.back().polyline_content.size() - // << " vertices, incident to " - // << polylines.back().context.adjacent_patches_ids.size() - // << " patches:\n "; - // for(auto p: polylines.back().polyline_content) - // std::cerr << " " << p; - // std::cerr << "\n"; - // } - } -}; - - -} // end CGAL::internal::Mesh_3 -} // end CGAL::internal - -/// @endcond /*! \ingroup PkgMesh_3Domains @@ -1035,7 +885,6 @@ add_features_from_split_graph_into_polylines(Featured_edges_copy_graph& g_copy) std::vector polylines; internal::Mesh_3::Extract_polyline_with_context_visitor< - Polyhedral_complex_mesh_domain_3, Polyline_with_context, Featured_edges_copy_graph > visitor(g_copy, polylines); diff --git a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h index 0650b628eef..45cdf910255 100644 --- a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h @@ -32,7 +32,6 @@ #include -#include #include #include @@ -68,6 +67,8 @@ // default) #include +#include + namespace CGAL { namespace Mesh_3 { @@ -82,24 +83,6 @@ max_length(const Bbox_3& b) (std::max)(b.ymax()-b.ymin(),b.zmax()-b.zmin()) ); } -// ----------------------------------- -// Index_generator -// Don't use boost::variant if types are the same type -// ----------------------------------- -template < typename Subdomain_index, typename Surface_patch_index > -struct Index_generator -{ - typedef boost::variant Index; - typedef Index type; -}; - -template < typename T > -struct Index_generator -{ - typedef T Index; - typedef Index type; -}; - // ----------------------------------- // Geometric traits generator // ----------------------------------- @@ -213,7 +196,7 @@ public: typedef boost::optional Surface_patch; /// Type of indexes to characterize the lowest dimensional face of the input /// complex on which a vertex lie - typedef typename Mesh_3::details::Index_generator< + typedef typename internal::Mesh_3::Index_generator< Subdomain_index, Surface_patch_index>::type Index; typedef CGAL::cpp11::tuple Intersection; diff --git a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h index ea04c0eb7e4..cf7e50f8cbc 100644 --- a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h +++ b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_with_features_3.h @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -62,132 +63,6 @@ namespace CGAL { -namespace internal { -namespace Mesh_3 { - -template -struct Angle_tester -{ - template - bool operator()(vertex_descriptor& v, const Graph& g) const - { - typedef typename boost::graph_traits::out_edge_iterator out_edge_iterator; - if (out_degree(v, g) != 2) - return true; - else - { - out_edge_iterator out_edge_it, out_edges_end; - boost::tie(out_edge_it, out_edges_end) = out_edges(v, g); - - vertex_descriptor v1 = target(*out_edge_it++, g); - vertex_descriptor v2 = target(*out_edge_it++, g); - CGAL_assertion(out_edge_it == out_edges_end); - - const typename Kernel::Point_3& p = g[v]; - const typename Kernel::Point_3& p1 = g[v1]; - const typename Kernel::Point_3& p2 = g[v2]; - - return (CGAL::angle(p1, p, p2) == CGAL::ACUTE); - } - } -}; - -template -struct Is_featured_edge { - const Polyhedron* polyhedron; - typename boost::property_map::type eifm; - Is_featured_edge() - : polyhedron(0) - {} // required by boost::filtered_graph - - Is_featured_edge(const Polyhedron& polyhedron) - : polyhedron(&polyhedron), eifm(get(edge_is_feature,polyhedron)) - {} - - bool operator()(typename boost::graph_traits::edge_descriptor e) const { - return get(eifm, e); - } -}; // end Is_featured_edge - -template -struct Is_border_edge { - const Polyhedron* polyhedron; - Is_border_edge() : polyhedron(0) {} // required by boost::filtered_graph - Is_border_edge(const Polyhedron& polyhedron) : polyhedron(&polyhedron) {} - - bool operator()(typename boost::graph_traits::edge_descriptor e) const { - return is_border(halfedge(e, *polyhedron), *polyhedron) || - is_border(opposite(halfedge(e, *polyhedron), *polyhedron), *polyhedron); - } -}; // end Is_featured_edge - -template -struct Extract_polyline_with_context_visitor -{ - typedef typename Polyhedral_mesh_domain::Polyhedron Polyhedron; - std::vector& polylines; - const Graph& graph; - - Extract_polyline_with_context_visitor - (const Graph& graph, - typename std::vector& polylines) - : polylines(polylines), graph(graph) - {} - - void start_new_polyline() - { - polylines.push_back(Polyline_with_context()); - } - - void add_node(typename boost::graph_traits::vertex_descriptor vd) - { - if(polylines.back().polyline_content.empty()) { - polylines.back().polyline_content.push_back(graph[vd]); - } - } - - void add_edge(typename boost::graph_traits::edge_descriptor ed) - { - typename boost::graph_traits::vertex_descriptor - s = source(ed, graph), - t = target(ed, graph); - Polyline_with_context& polyline = polylines.back(); - CGAL_assertion(!polyline.polyline_content.empty()); - if(polyline.polyline_content.back() != graph[s]) { - polyline.polyline_content.push_back(graph[s]); - } else if(polyline.polyline_content.back() != graph[t]) { - // if the edge is zero-length, it is ignored - polyline.polyline_content.push_back(graph[t]); - } - const typename boost::edge_bundle_type::type & - set_of_indices = graph[ed]; - polyline.context.adjacent_patches_ids.insert(set_of_indices.begin(), - set_of_indices.end()); - } - - void end_polyline() - { - // ignore degenerated polylines - if(polylines.back().polyline_content.size() < 2) - polylines.resize(polylines.size() - 1); - // else { - // std::cerr << "Polyline with " << polylines.back().polyline_content.size() - // << " vertices, incident to " - // << polylines.back().context.adjacent_patches_ids.size() - // << " patches:\n "; - // for(auto p: polylines.back().polyline_content) - // std::cerr << " " << p; - // std::cerr << "\n"; - // } - } -}; - - -} // end CGAL::internal::Mesh_3 -} // end CGAL::internal - /** * @class Polyhedral_mesh_domain_with_features_3 * @@ -219,6 +94,7 @@ class Polyhedral_mesh_domain_with_features_3 std::set > Featured_edges_copy_graph; public: typedef Polyhedron_ Polyhedron; + typedef Polyhedron Polyhedron_type; // Index types typedef typename Base::Index Index; @@ -262,6 +138,8 @@ public: this->build(); } +#ifndef CGAL_NO_DEPRECATED_CODE + CGAL_DEPRECATED Polyhedral_mesh_domain_with_features_3(const std::string& filename, CGAL::Random* p_rng = NULL) @@ -280,6 +158,7 @@ public: { load_from_file(filename); } +#endif // not CGAL_NO_DEPRECATED_CODE Polyhedral_mesh_domain_with_features_3(const Polyhedron& p, const Polyhedron& bounding_p, @@ -516,7 +395,6 @@ add_features_from_split_graph_into_polylines(Featured_edges_copy_graph& g_copy) std::vector polylines; internal::Mesh_3::Extract_polyline_with_context_visitor< - Polyhedral_mesh_domain_with_features_3, Polyline_with_context, Featured_edges_copy_graph > visitor(g_copy, polylines); diff --git a/Mesh_3/include/CGAL/exude_mesh_3.h b/Mesh_3/include/CGAL/exude_mesh_3.h index ba74aa72111..9f4a018cea5 100644 --- a/Mesh_3/include/CGAL/exude_mesh_3.h +++ b/Mesh_3/include/CGAL/exude_mesh_3.h @@ -34,8 +34,8 @@ #include #include #include -#include -#include +#include +#include namespace CGAL { @@ -46,8 +46,8 @@ namespace CGAL { // see CGAL_PRAGMA_DIAG_PUSH -// see -CGAL_MESH_3_IGNORE_BOOST_PARAMETER_NAME_WARNINGS +// see +CGAL_IGNORE_BOOST_PARAMETER_NAME_WARNINGS BOOST_PARAMETER_FUNCTION( (Mesh_optimization_return_code), diff --git a/Mesh_3/include/CGAL/internal/Mesh_3/Graph_manipulations.h b/Mesh_3/include/CGAL/internal/Mesh_3/Graph_manipulations.h index fec1373724e..3d3f8d4957a 100644 --- a/Mesh_3/include/CGAL/internal/Mesh_3/Graph_manipulations.h +++ b/Mesh_3/include/CGAL/internal/Mesh_3/Graph_manipulations.h @@ -54,22 +54,43 @@ struct Graph_manipulations , interpolate(interpolate) {} - vertex_descriptor get_vertex(const Point_3& p) { + static vertex_descriptor null_vertex() { + return boost::graph_traits::null_vertex(); + } + + vertex_descriptor get_vertex(const Point_3& p, bool force_terminal) { typename std::map::iterator it = p2v.find(p); if(it == p2v.end()){ vertex_descriptor v0 = add_vertex(g); p2v[p] = v0; g[v0] = p; + g[v0].force_terminal = force_terminal; return v0; } else { return it->second; } } + template + vertex_descriptor split(const Enriched_pixel& epa, + const Enriched_pixel& epb, + const Null& null) + { + return split(epa.point, + epb.point, + epa.word, + epb.word, + null(epa.domain), + null(epb.domain), + epa.on_edge_of_the_cube, + epb.on_edge_of_the_cube); + } + vertex_descriptor split(const Point_3& a, const Point_3& b, const NT v_a, const NT v_b, - bool a_is_outside, bool b_is_outside) + bool a_is_outside, bool b_is_outside, + bool a_on_edge, bool b_on_edge) { #ifdef CGAL_MESH_3_DEBUG_GRAPH_MANIPULATION std::cerr << "split(" << a << ", " << b << ", " @@ -78,7 +99,7 @@ struct Graph_manipulations #endif // CGAL_MESH_3_DEBUG_GRAPH_MANIPULATION const Point_3 mid = interpolate(a, b, v_a, v_b); - vertex_descriptor vmid = get_vertex(mid); + vertex_descriptor vmid = get_vertex(mid, a_on_edge && b_on_edge); typename std::map::iterator it_a = p2v.find(a), it_b = p2v.find(b); @@ -108,8 +129,11 @@ struct Graph_manipulations bool try_add_edge(vertex_descriptor v1, vertex_descriptor v2) { #ifdef CGAL_MESH_3_DEBUG_GRAPH_MANIPULATION - std::cerr << "try_add_edge(" << v1 << " (" << g[v1] - << "), " << v2 << " (" << g[v2] << "))\n"; + std::cerr << "try_add_edge(" << v1 << " (" << g[v1].point + << ", " << std::boolalpha << g[v1].force_terminal + << "), " << v2 << " (" << g[v2].point + << ", " << std::boolalpha << g[v2].force_terminal + << "))\n"; #endif // CGAL_MESH_3_DEBUG_GRAPH_MANIPULATION if(v1 != v2) { edge_descriptor edge; diff --git a/Mesh_3/include/CGAL/internal/Mesh_3/get_index.h b/Mesh_3/include/CGAL/internal/Mesh_3/get_index.h index 8b091e5a1a0..df6b1d681f9 100644 --- a/Mesh_3/include/CGAL/internal/Mesh_3/get_index.h +++ b/Mesh_3/include/CGAL/internal/Mesh_3/get_index.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 INRIA Sophia-Antipolis (France). +// Copyright (c) 2018 GeometryFactory Sarl (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org). @@ -16,12 +16,11 @@ // $Id$ // SPDX-License-Identifier: GPL-3.0+ // -// Author(s) : Stéphane Tayeb +// Author(s) : Laurent Rineau // //****************************************************************************** -// File Description : -// -// +// File Description : trivial backward-compatibility for undocumented +// classes/function templates //****************************************************************************** #ifndef CGAL_INTERNAL_MESH_3_GET_INDEX_3_H @@ -29,146 +28,6 @@ #include +#include -#include -#include -#include - -namespace CGAL { -namespace internal { -namespace Mesh_3 { - - -template -const T& get_index(const Boost_variant& x, - typename boost::disable_if >::type * = 0) -{ return boost::get(x); } - -template -const T& get_index(const T& x) { return x; } - -template ::value> -struct Read_mesh_domain_index { - // here we have has_feature==true - - typedef Mesh_domain MT; // was named "mesh traits" previously - - typename Mesh_domain::Index - operator()(int dimension, std::istream& is) const { - switch(dimension) { - case 0: - typename MT::Corner_index ci; - if(is_ascii(is)) is >> ci; - else CGAL::read(is, ci); - return ci; - break; - case 1: - typename MT::Curve_index si; - if(is_ascii(is)) is >> si; - else CGAL::read(is, si); - return si; - break; - default: - return Read_mesh_domain_index()(dimension, is); - } - } -}; // end template partial specialization - // Read_mesh_domain_index - -template ::value> -struct Write_mesh_domain_index { - // here we have has_feature==true - - typedef Mesh_domain MT; // was named "mesh traits" previously - typedef typename MT::Corner_index Ci; - typedef typename MT::Curve_index Si; - - void - operator()(std::ostream& os, int dimension, - const typename Mesh_domain::Index& index) const { - switch(dimension) { - case 0: { - const Ci& ci = get_index(index); - if(is_ascii(os)) os << oformat(ci); - else CGAL::write(os, ci); - } - break; - case 1: { - const Si& si = get_index(index); - if(is_ascii(os)) os << oformat(si); - else CGAL::write(os, si); - } - break; - default: - Write_mesh_domain_index()(os, dimension, index); - } - } -}; // end template partial specialization - // Write_mesh_domain_index - -template -struct Read_mesh_domain_index { - // here we have has_feature==false - - typedef Mesh_domain MT; // was named "mesh traits" previously - - typename Mesh_domain::Index - operator()(int dimension, std::istream& is) const { - switch(dimension) { - case 2: { - typename MT::Surface_patch_index spi; - if(is_ascii(is)) is >> iformat(spi); - else CGAL::read(is, spi); - return spi; - } - break; - default: {// 3 - typename MT::Subdomain_index di; - if(is_ascii(is)) is >> iformat(di); - else CGAL::read(is, di); - return di; - } - break; - } - } -}; // end template partial specialization - // Read_mesh_domain_index - -template -struct Write_mesh_domain_index { - // here we have has_feature==false - - typedef Mesh_domain MT; // was named "mesh traits" previously - typedef typename MT::Surface_patch_index Spi; - typedef typename MT::Subdomain_index Di; - - void - operator()(std::ostream& os, int dimension, - const typename Mesh_domain::Index& index) const { - switch(dimension) { - case 2: { - const Spi& spi = get_index(index); - if(is_ascii(os)) os << oformat(spi); - else CGAL::write(os, spi); - } - break; - default: {// 3 - const Di& di = get_index(index); - if(is_ascii(os)) os << oformat(di); - else CGAL::write(os, di); - } - break; - } - } -}; // end template partial specialization - // Write_mesh_domain_index - - - -} -} -} - -#endif +#endif // CGAL_INTERNAL_MESH_3_GET_INDEX_3_H diff --git a/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h b/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h new file mode 100644 index 00000000000..9c728889c46 --- /dev/null +++ b/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h @@ -0,0 +1,193 @@ +// Copyright (c) 2009-2010 INRIA Sophia-Antipolis (France). +// Copyright (c) 2014-2017 GeometryFactory Sarl (France) +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// +// Author(s) : Laurent Rineau, Stéphane Tayeb +// +//****************************************************************************** +// File Description : +// +//****************************************************************************** + +#ifndef CGAL_MESH_3_INTERNAL_MESH_3_HELPERS_H +#define CGAL_MESH_3_INTERNAL_MESH_3_HELPERS_H + +#include + +#include +#include +#include +#include + +namespace CGAL { + +/// @cond DEVELOPERS +namespace internal { +namespace Mesh_3 { + +template +void dump_graph_edges(std::ostream& out, const Graph& g) +{ + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::edge_descriptor edge_descriptor; + + out.precision(17); + BOOST_FOREACH(edge_descriptor e, edges(g)) + { + vertex_descriptor s = source(e, g); + vertex_descriptor t = target(e, g); + out << "2 " << g[s] << " " << g[t] << "\n"; + } +} + +template +void dump_graph_edges(const char* filename, const Graph& g) +{ + std::ofstream out(filename); + dump_graph_edges(out, g); +} + +template +struct Angle_tester +{ + template + bool operator()(vertex_descriptor& v, const Graph& g) const + { + typedef typename boost::graph_traits::out_edge_iterator out_edge_iterator; + if (out_degree(v, g) != 2) + return true; + else + { + out_edge_iterator out_edge_it, out_edges_end; + boost::tie(out_edge_it, out_edges_end) = out_edges(v, g); + + vertex_descriptor v1 = target(*out_edge_it++, g); + vertex_descriptor v2 = target(*out_edge_it++, g); + CGAL_assertion(out_edge_it == out_edges_end); + + const typename Kernel::Point_3& p = g[v]; + const typename Kernel::Point_3& p1 = g[v1]; + const typename Kernel::Point_3& p2 = g[v2]; + + return (CGAL::angle(p1, p, p2) == CGAL::ACUTE); + } + } +}; + +template +struct Is_featured_edge { + const Polyhedron* polyhedron; + typename boost::property_map::type eifm; + Is_featured_edge() + : polyhedron(0) + {} // required by boost::filtered_graph + + Is_featured_edge(const Polyhedron& polyhedron) + : polyhedron(&polyhedron), eifm(get(edge_is_feature,polyhedron)) + {} + + bool operator()(typename boost::graph_traits::edge_descriptor e) const { + return get(eifm, e); + } +}; // end Is_featured_edge + +template +struct Is_border_edge { + const Polyhedron* polyhedron; + Is_border_edge() : polyhedron(0) {} // required by boost::filtered_graph + Is_border_edge(const Polyhedron& polyhedron) : polyhedron(&polyhedron) {} + + bool operator()(typename boost::graph_traits::edge_descriptor e) const { + return is_border(halfedge(e, *polyhedron), *polyhedron) || + is_border(opposite(halfedge(e, *polyhedron), *polyhedron), *polyhedron); + } +}; // end Is_featured_edge + +template +struct Extract_polyline_with_context_visitor +{ + std::vector& polylines; + const Graph& graph; + + Extract_polyline_with_context_visitor + (const Graph& graph, + typename std::vector& polylines) + : polylines(polylines), graph(graph) + {} + + void start_new_polyline() + { + polylines.push_back(Polyline_with_context()); + } + + void add_node(typename boost::graph_traits::vertex_descriptor vd) + { + if(polylines.back().polyline_content.empty()) { + polylines.back().polyline_content.push_back(graph[vd]); + } + } + + void add_edge(typename boost::graph_traits::edge_descriptor ed) + { + typename boost::graph_traits::vertex_descriptor + s = source(ed, graph), + t = target(ed, graph); + Polyline_with_context& polyline = polylines.back(); + CGAL_assertion(!polyline.polyline_content.empty()); + if(polyline.polyline_content.back() != graph[s]) { + polyline.polyline_content.push_back(graph[s]); + } else if(polyline.polyline_content.back() != graph[t]) { + // if the edge is zero-length, it is ignored + polyline.polyline_content.push_back(graph[t]); + } + const typename boost::edge_bundle_type::type & + set_of_indices = graph[ed]; + polyline.context.adjacent_patches_ids.insert(set_of_indices.begin(), + set_of_indices.end()); + } + + void end_polyline() + { + // ignore degenerated polylines + if(polylines.back().polyline_content.size() < 2) + polylines.resize(polylines.size() - 1); + // else { + // std::cerr << "Polyline with " << polylines.back().polyline_content.size() + // << " vertices, incident to " + // << polylines.back().context.adjacent_patches_ids.size() + // << " patches:\n "; + // for(auto p: polylines.back().polyline_content) + // std::cerr << " " << p; + // std::cerr << "\n"; + // } + } +}; + + +} // end CGAL::internal::Mesh_3 +} // end CGAL::internal + +/// @endcond + +} // end CGAL + +#include + +#endif // CGAL_MESH_3_INTERNAL_MESH_3_HELPERS_H diff --git a/Mesh_3/include/CGAL/internal/Mesh_3/indices_management.h b/Mesh_3/include/CGAL/internal/Mesh_3/indices_management.h new file mode 100644 index 00000000000..595ed00829a --- /dev/null +++ b/Mesh_3/include/CGAL/internal/Mesh_3/indices_management.h @@ -0,0 +1,194 @@ +// Copyright (c) 2009 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// Author(s) : Stéphane Tayeb +// +//****************************************************************************** +// File Description : +// +// +//****************************************************************************** + +#ifndef CGAL_INTERNAL_MESH_3_INDICES_MANAGEMENT_H +#define CGAL_INTERNAL_MESH_3_INDICES_MANAGEMENT_H + +#include + + +#include +#include +#include +#include +#include + +namespace CGAL { +namespace internal { +namespace Mesh_3 { + + +// ----------------------------------- +// Index_generator +// Don't use boost::variant if types are the same type +// ----------------------------------- +template < typename Subdomain_index, typename Surface_patch_index > +struct Index_generator +{ + typedef boost::variant Index; + typedef Index type; +}; + +template < typename T > +struct Index_generator +{ + typedef T Index; + typedef Index type; +}; + +template +const T& get_index(const Boost_variant& x, + typename boost::disable_if >::type * = 0) +{ return boost::get(x); } + +template +const T& get_index(const T& x) { return x; } + +template ::value> +struct Read_mesh_domain_index { + // here we have has_feature==true + + typedef Mesh_domain MT; // was named "mesh traits" previously + + typename Mesh_domain::Index + operator()(int dimension, std::istream& is) const { + switch(dimension) { + case 0: + typename MT::Corner_index ci; + if(is_ascii(is)) is >> ci; + else CGAL::read(is, ci); + return ci; + break; + case 1: + typename MT::Curve_index si; + if(is_ascii(is)) is >> si; + else CGAL::read(is, si); + return si; + break; + default: + return Read_mesh_domain_index()(dimension, is); + } + } +}; // end template partial specialization + // Read_mesh_domain_index + +template ::value> +struct Write_mesh_domain_index { + // here we have has_feature==true + + typedef Mesh_domain MT; // was named "mesh traits" previously + typedef typename MT::Corner_index Ci; + typedef typename MT::Curve_index Si; + + void + operator()(std::ostream& os, int dimension, + const typename Mesh_domain::Index& index) const { + switch(dimension) { + case 0: { + const Ci& ci = get_index(index); + if(is_ascii(os)) os << oformat(ci); + else CGAL::write(os, ci); + } + break; + case 1: { + const Si& si = get_index(index); + if(is_ascii(os)) os << oformat(si); + else CGAL::write(os, si); + } + break; + default: + Write_mesh_domain_index()(os, dimension, index); + } + } +}; // end template partial specialization + // Write_mesh_domain_index + +template +struct Read_mesh_domain_index { + // here we have has_feature==false + + typedef Mesh_domain MT; // was named "mesh traits" previously + + typename Mesh_domain::Index + operator()(int dimension, std::istream& is) const { + switch(dimension) { + case 2: { + typename MT::Surface_patch_index spi; + if(is_ascii(is)) is >> iformat(spi); + else CGAL::read(is, spi); + return spi; + } + break; + default: {// 3 + typename MT::Subdomain_index di; + if(is_ascii(is)) is >> iformat(di); + else CGAL::read(is, di); + return di; + } + break; + } + } +}; // end template partial specialization + // Read_mesh_domain_index + +template +struct Write_mesh_domain_index { + // here we have has_feature==false + + typedef Mesh_domain MT; // was named "mesh traits" previously + typedef typename MT::Surface_patch_index Spi; + typedef typename MT::Subdomain_index Di; + + void + operator()(std::ostream& os, int dimension, + const typename Mesh_domain::Index& index) const { + switch(dimension) { + case 2: { + const Spi& spi = get_index(index); + if(is_ascii(os)) os << oformat(spi); + else CGAL::write(os, spi); + } + break; + default: {// 3 + const Di& di = get_index(index); + if(is_ascii(os)) os << oformat(di); + else CGAL::write(os, di); + } + break; + } + } +}; // end template partial specialization + // Write_mesh_domain_index + + + +} +} +} + +#endif // CGAL_INTERNAL_MESH_3_INDICES_MANAGEMENT_H diff --git a/Mesh_3/include/CGAL/lloyd_optimize_mesh_3.h b/Mesh_3/include/CGAL/lloyd_optimize_mesh_3.h index 63ed1d0a73e..a86f6f4f994 100644 --- a/Mesh_3/include/CGAL/lloyd_optimize_mesh_3.h +++ b/Mesh_3/include/CGAL/lloyd_optimize_mesh_3.h @@ -30,7 +30,8 @@ #include -#include +#include +#include #include #include #include @@ -47,8 +48,8 @@ namespace CGAL { // see CGAL_PRAGMA_DIAG_PUSH -// see -CGAL_MESH_3_IGNORE_BOOST_PARAMETER_NAME_WARNINGS +// see +CGAL_IGNORE_BOOST_PARAMETER_NAME_WARNINGS BOOST_PARAMETER_FUNCTION( (Mesh_optimization_return_code), diff --git a/Mesh_3/include/CGAL/make_mesh_3.h b/Mesh_3/include/CGAL/make_mesh_3.h index 7c54c459f00..36e1d155d17 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -31,7 +31,8 @@ #include #include -#include +#include +#include #include #include #include @@ -123,8 +124,8 @@ namespace parameters { // see CGAL_PRAGMA_DIAG_PUSH -// see -CGAL_MESH_3_IGNORE_BOOST_PARAMETER_NAME_WARNINGS +// see +CGAL_IGNORE_BOOST_PARAMETER_NAME_WARNINGS BOOST_PARAMETER_NAME( features_param ) @@ -404,8 +405,8 @@ C3T3 make_mesh_3(const MD& md, const MC& mc, const Arg1& a1, const Arg2& a2, // see CGAL_PRAGMA_DIAG_PUSH -// see -CGAL_MESH_3_IGNORE_BOOST_PARAMETER_NAME_WARNINGS +// see +CGAL_IGNORE_BOOST_PARAMETER_NAME_WARNINGS BOOST_PARAMETER_FUNCTION( (void), diff --git a/Mesh_3/include/CGAL/odt_optimize_mesh_3.h b/Mesh_3/include/CGAL/odt_optimize_mesh_3.h index 57b7181c850..163b5cf28bd 100644 --- a/Mesh_3/include/CGAL/odt_optimize_mesh_3.h +++ b/Mesh_3/include/CGAL/odt_optimize_mesh_3.h @@ -30,7 +30,8 @@ #include -#include +#include +#include #include #include #include @@ -47,8 +48,8 @@ namespace CGAL { // see CGAL_PRAGMA_DIAG_PUSH -// see -CGAL_MESH_3_IGNORE_BOOST_PARAMETER_NAME_WARNINGS +// see +CGAL_IGNORE_BOOST_PARAMETER_NAME_WARNINGS BOOST_PARAMETER_FUNCTION( (Mesh_optimization_return_code), diff --git a/Mesh_3/include/CGAL/perturb_mesh_3.h b/Mesh_3/include/CGAL/perturb_mesh_3.h index 59291afe48e..2982717043e 100644 --- a/Mesh_3/include/CGAL/perturb_mesh_3.h +++ b/Mesh_3/include/CGAL/perturb_mesh_3.h @@ -30,7 +30,8 @@ #include -#include +#include +#include #include #include #include @@ -48,8 +49,8 @@ namespace CGAL { // see CGAL_PRAGMA_DIAG_PUSH -// see -CGAL_MESH_3_IGNORE_BOOST_PARAMETER_NAME_WARNINGS +// see +CGAL_IGNORE_BOOST_PARAMETER_NAME_WARNINGS BOOST_PARAMETER_FUNCTION( (Mesh_optimization_return_code), diff --git a/Mesh_3/include/CGAL/refine_mesh_3.h b/Mesh_3/include/CGAL/refine_mesh_3.h index fb3e4aee3d4..4c21d5ef81d 100644 --- a/Mesh_3/include/CGAL/refine_mesh_3.h +++ b/Mesh_3/include/CGAL/refine_mesh_3.h @@ -31,9 +31,10 @@ #include #include +#include +#include #include #include -#include #include #include #include @@ -236,8 +237,8 @@ namespace parameters { // see CGAL_PRAGMA_DIAG_PUSH -// see -CGAL_MESH_3_IGNORE_BOOST_PARAMETER_NAME_WARNINGS +// see +CGAL_IGNORE_BOOST_PARAMETER_NAME_WARNINGS // ----------------------------------- @@ -412,14 +413,14 @@ CGAL_PRAGMA_DIAG_POP // ----------------------------------- // Reset_c3t3 (undocumented) // ----------------------------------- - CGAL_MESH_BOOLEAN_PARAMETER(Reset,reset_c3t3,no_reset_c3t3) - // CGAL_MESH_BOOLEAN_PARAMETER defined in + CGAL_BOOLEAN_PARAMETER(Reset,reset_c3t3,no_reset_c3t3) + // CGAL_BOOLEAN_PARAMETER defined in // see CGAL_PRAGMA_DIAG_PUSH -// see -CGAL_MESH_3_IGNORE_BOOST_PARAMETER_NAME_WARNINGS +// see +CGAL_IGNORE_BOOST_PARAMETER_NAME_WARNINGS // ----------------------------------- // Parameters @@ -445,8 +446,8 @@ CGAL_PRAGMA_DIAG_POP // see CGAL_PRAGMA_DIAG_PUSH -// see -CGAL_MESH_3_IGNORE_BOOST_PARAMETER_NAME_WARNINGS +// see +CGAL_IGNORE_BOOST_PARAMETER_NAME_WARNINGS BOOST_PARAMETER_FUNCTION( (void), diff --git a/Mesh_3/test/Mesh_3/CMakeLists.txt b/Mesh_3/test/Mesh_3/CMakeLists.txt index 9eb5f4fb69a..3a3302cc942 100644 --- a/Mesh_3/test/Mesh_3/CMakeLists.txt +++ b/Mesh_3/test/Mesh_3/CMakeLists.txt @@ -24,19 +24,18 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "test_c3t3.cpp" ) create_single_source_cgal_program( "test_mesh_capsule_var_distance_bound.cpp" ) create_single_source_cgal_program( "test_implicit_multi_domain_to_labeling_function_wrapper.cpp" ) - create_single_source_cgal_program( "test_mesh_3_implicit_vector_to_labeled_function_wrapper.cpp" ) create_single_source_cgal_program( "test_c3t3_io.cpp" ) create_single_source_cgal_program( "test_c3t3_with_features.cpp" ) create_single_source_cgal_program( "test_criteria.cpp" ) create_single_source_cgal_program( "test_domain_with_polyline_features.cpp" ) - create_single_source_cgal_program( "test_mesh_3_labeled_mesh_domain_3.cpp" ) - create_single_source_cgal_program( "test_mesh_implicit_domains.cpp" "implicit_functions.cpp" ) create_single_source_cgal_program( "test_labeled_mesh_domain_3.cpp" ) create_single_source_cgal_program( "test_mesh_criteria_creation.cpp" ) create_single_source_cgal_program( "test_c3t3_into_facegraph.cpp" ) if(CGAL_ImageIO_USE_ZLIB) create_single_source_cgal_program( "test_meshing_3D_image.cpp" ) + create_single_source_cgal_program( "test_meshing_3D_image_deprecated.cpp" ) create_single_source_cgal_program( "test_meshing_3D_gray_image.cpp" ) + create_single_source_cgal_program( "test_meshing_3D_gray_image_deprecated.cpp" ) else() message(STATUS "test_meshing_3D_image requires the ZLIB library, and will not be compiled.") endif() @@ -45,14 +44,17 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "test_meshing_polyhedron.cpp" ) create_single_source_cgal_program( "test_meshing_polylines_only.cpp" ) create_single_source_cgal_program( "test_meshing_polyhedron_with_features.cpp" ) + create_single_source_cgal_program( "test_meshing_verbose.cpp" ) create_single_source_cgal_program( "test_meshing_unit_tetrahedron.cpp" ) create_single_source_cgal_program( "test_meshing_with_default_edge_size.cpp" ) create_single_source_cgal_program( "test_meshing_determinism.cpp" ) create_single_source_cgal_program( "test_c3t3_extract_subdomains_boundaries.cpp" ) create_single_source_cgal_program( "test_mesh_3_issue_1554.cpp" ) create_single_source_cgal_program( "test_mesh_polyhedral_domain_with_features_deprecated.cpp" ) + create_single_source_cgal_program( "test_meshing_with_one_step.cpp" ) foreach(target + test_meshing_verbose test_meshing_polyhedron_with_features test_meshing_utilities.h test_mesh_implicit_domains diff --git a/Mesh_3/test/Mesh_3/implicit_functions.h b/Mesh_3/test/Mesh_3/implicit_functions.h index debbd838480..f5293a87028 100644 --- a/Mesh_3/test/Mesh_3/implicit_functions.h +++ b/Mesh_3/test/Mesh_3/implicit_functions.h @@ -25,7 +25,7 @@ double sphere_function (double x, double y, double z) // (c=(0,0,0), r=Sq_radius template -class FT_to_point_function_wrapper : public CGAL::unary_function +class FT_to_point_function_wrapper : public CGAL::cpp98::unary_function { typedef FT (*Implicit_function)(FT, FT, FT); Implicit_function function; diff --git a/Mesh_3/test/Mesh_3/test_backward_compatibility.cpp b/Mesh_3/test/Mesh_3/test_backward_compatibility.cpp index 7234e312c63..b6b47880cc1 100644 --- a/Mesh_3/test/Mesh_3/test_backward_compatibility.cpp +++ b/Mesh_3/test/Mesh_3/test_backward_compatibility.cpp @@ -18,7 +18,7 @@ // // Author(s) : Laurent Rineau -#ifndef CGAL_NO_DEPRECATED_CODE +#include #include @@ -155,11 +155,3 @@ int main() return 0; } - -#else // CGAL_NO_DEPRECATED_CODE -#include -int main() { - std::cerr << "CGAL_NO_DEPRECATED_CODE is defined. Nothing to test.\n"; - return 0; -} -#endif // CGAL_NO_DEPRECATED_CODE diff --git a/Mesh_3/test/Mesh_3/test_c3t3.cpp b/Mesh_3/test/Mesh_3/test_c3t3.cpp index 1c296cbb970..83eae437387 100644 --- a/Mesh_3/test/Mesh_3/test_c3t3.cpp +++ b/Mesh_3/test/Mesh_3/test_c3t3.cpp @@ -32,7 +32,7 @@ // IO #include #include -#include +#include #include #include diff --git a/Mesh_3/test/Mesh_3/test_c3t3_extract_subdomains_boundaries.cpp b/Mesh_3/test/Mesh_3/test_c3t3_extract_subdomains_boundaries.cpp index f606a7821da..54c31079acf 100644 --- a/Mesh_3/test/Mesh_3/test_c3t3_extract_subdomains_boundaries.cpp +++ b/Mesh_3/test/Mesh_3/test_c3t3_extract_subdomains_boundaries.cpp @@ -24,7 +24,7 @@ double sphere_function (double x, double y, double z) // (c=(0,0,0), r=Sq_radius } template -class FT_to_point_function_wrapper : public CGAL::unary_function +class FT_to_point_function_wrapper : public CGAL::cpp98::unary_function { typedef FT (*Implicit_function)(FT, FT, FT); Implicit_function function; @@ -46,7 +46,7 @@ typedef FT_to_point_function_wrapper Function; typedef CGAL::Implicit_multi_domain_to_labeling_function_wrapper Function_wrapper; typedef Function_wrapper::Function_vector Function_vector; -typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; // Triangulation typedef CGAL::Mesh_triangulation_3::type Tr; @@ -68,7 +68,7 @@ int main() v.push_back(f1); v.push_back(f2); // Domain (Warning: Sphere_3 constructor uses square radius !) - Mesh_domain domain(v, K::Sphere_3(CGAL::ORIGIN, 5.*5.), 1e-6); + Mesh_domain domain(Function_wrapper(v), K::Sphere_3(CGAL::ORIGIN, 5.*5.), 1e-6); // Set mesh criteria Facet_criteria facet_criteria(30, 0.2, 0.02); // angle, size, approximation diff --git a/Mesh_3/test/Mesh_3/test_c3t3_with_features.cpp b/Mesh_3/test/Mesh_3/test_c3t3_with_features.cpp index 3d0c27a5f60..1cdccbfd80f 100644 --- a/Mesh_3/test/Mesh_3/test_c3t3_with_features.cpp +++ b/Mesh_3/test/Mesh_3/test_c3t3_with_features.cpp @@ -27,7 +27,7 @@ #include "test_utilities.h" -#include +#include #include // IO @@ -40,9 +40,7 @@ template struct Tester { - typedef typename K::FT (Function)(const typename K::Point_3&); - - typedef CGAL::Implicit_mesh_domain_3 Base_domain; + typedef CGAL::Labeled_mesh_domain_3 Base_domain; typedef CGAL::Mesh_domain_with_polyline_features_3 Md; typedef typename CGAL::Mesh_triangulation_3::type Tr; typedef CGAL::Mesh_complex_3_in_triangulation_3< diff --git a/Mesh_3/test/Mesh_3/test_domain_with_polyline_features.cpp b/Mesh_3/test/Mesh_3/test_domain_with_polyline_features.cpp index 29436d1973e..5123829ce97 100644 --- a/Mesh_3/test/Mesh_3/test_domain_with_polyline_features.cpp +++ b/Mesh_3/test/Mesh_3/test_domain_with_polyline_features.cpp @@ -53,18 +53,34 @@ class Domain_with_polyline_tester typedef Mesh_domain::Corner_index Ci; typedef Mesh_domain::Curve_index Csi; + typedef Mesh_domain::Surface_patch_index Spi; typedef Mesh_domain::Index Index; typedef std::vector > Corners_vector; typedef std::pair P_and_i; typedef CGAL::cpp11::tuple Curve_tuple; - typedef std::vector Curves_vector; + typedef std::vector Curves_vector; public: Domain_with_polyline_tester() : p1_(1,0,0), p2_(1,1,0), p3_(1,2,0.1), p4_(0.9, 0.9, 1) { } - + + void build_corners() + { + domain_.add_corner(p1_); + + std::vector corners; + corners.push_back(p2_); + domain_.add_corners(corners.begin(), corners.end()); + + Csi dummy_curve_index = 12; + domain_.register_corner(p3_, dummy_curve_index); + + Spi dummy_surface_patch_index = 21; + domain_.add_corner_with_context(p4_, dummy_surface_patch_index); + } + void build_curve() { Polylines polylines (1); @@ -90,7 +106,35 @@ public: domain_.add_features(polylines.begin(),polylines.end()); } - + + void test_corners() const + { + Corners_vector corners; + domain_.get_corners(std::back_inserter(corners)); + assert(corners.size() == 4); + + Corners_vector::const_iterator cit = corners.begin(), end = corners.end(); + for(; cit!=end; ++cit) + { + if(cit->second == p3_) + { + std::vector incident_curves; + domain_.get_corner_incident_curves(cit->first, std::back_inserter(incident_curves)); + assert(incident_curves.size() == 1 && incident_curves.front() == 12); + } + else if(cit->second == p4_) + { + std::vector incident_surface_patchs; + domain_.get_corner_incidences(cit->first, std::back_inserter(incident_surface_patchs)); + assert(incident_surface_patchs.size() == 1 && incident_surface_patchs.front() == 21); + } + else + { + assert(cit->second == p1_ || cit->second == p2_); + } + } + } + void test_curve_corners() const { Corners_vector corners; @@ -192,6 +236,11 @@ private: int main() { + std::cout << "Test corners" << std::endl; + Domain_with_polyline_tester domain_corner_tester; + domain_corner_tester.build_corners(); + domain_corner_tester.test_corners(); + std::cout << "Test curve segments" << std::endl; Domain_with_polyline_tester domain_tester; domain_tester.build_curve(); diff --git a/Mesh_3/test/Mesh_3/test_labeled_mesh_domain_3.cpp b/Mesh_3/test/Mesh_3/test_labeled_mesh_domain_3.cpp index 97f0b9ff927..8045a6772a5 100644 --- a/Mesh_3/test/Mesh_3/test_labeled_mesh_domain_3.cpp +++ b/Mesh_3/test/Mesh_3/test_labeled_mesh_domain_3.cpp @@ -47,7 +47,7 @@ struct LM3_tester }; typedef CGAL::Implicit_to_labeling_function_wrapper Function_wrapper; - typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; + typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; static FT shape_function (const Point_3& p) { diff --git a/Mesh_3/test/Mesh_3/test_mesh_3_implicit_vector_to_labeled_function_wrapper.cpp b/Mesh_3/test/Mesh_3/test_mesh_3_implicit_vector_to_labeled_function_wrapper.cpp deleted file mode 100644 index 3a45601d56c..00000000000 --- a/Mesh_3/test/Mesh_3/test_mesh_3_implicit_vector_to_labeled_function_wrapper.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#define CGAL_NO_DEPRECATION_WARNINGS 1 - -#include -#include - - -typedef CGAL::Exact_predicates_inexact_constructions_kernel K_e_i; -typedef K_e_i::Point_3 Point_3; -typedef double (Function) (const Point_3&); - -typedef CGAL::Mesh_3::Implicit_vector_to_labeled_function_wrapper Labeling_function; -typedef Labeling_function::Function_vector Function_vector; - - -double cube_function_1 (const Point_3& p) -{ - if( p.x() > 0 && p.x() < 2 && - p.y() > 0 && p.y() < 2 && - p.z() > 0 && p.z() < 2 ) - return -1.; - return 1.; -} - -double cube_function_2 (const Point_3& p) -{ - if( p.x() > 1 && p.x() < 3 && - p.y() > 1 && p.y() < 3 && - p.z() > 1 && p.z() < 3 ) - return -1.; - return 1.; -} - - -void test_constructor_vfunc () -{ - Function_vector vfunc; - vfunc.push_back(cube_function_1); - vfunc.push_back(cube_function_2); - - Labeling_function lfunc(vfunc); - - Point_3 p1(0.5, 0.5, 0.5); - Point_3 p2(2.5, 2.5, 2.5); - Point_3 p3(1.5, 1.5, 1.5); - Point_3 p_out(4., 4., 4.); - - Labeling_function::return_type rp1 = lfunc(p1); - Labeling_function::return_type rp2 = lfunc(p2); - Labeling_function::return_type rp3 = lfunc(p3); - Labeling_function::return_type rp_out = lfunc(p_out); - - assert(rp1 != 0); - assert(rp2 != 0); - assert(rp3 != 0); - assert(rp_out == 0); - - assert(rp1 != rp2); - assert(rp1 != rp3); - assert(rp2 != rp3); -} - -int main () -{ - test_constructor_vfunc(); - return 0; -} diff --git a/Mesh_3/test/Mesh_3/test_mesh_3_issue_1554.cpp b/Mesh_3/test/Mesh_3/test_mesh_3_issue_1554.cpp index 998e4588162..034b1e4d067 100644 --- a/Mesh_3/test/Mesh_3/test_mesh_3_issue_1554.cpp +++ b/Mesh_3/test/Mesh_3/test_mesh_3_issue_1554.cpp @@ -1,3 +1,7 @@ +// Mesh_3 bug: The surface of c3t3 has holes +// +// https://github.com/CGAL/cgal/issues/1554 +// #include #include diff --git a/Mesh_3/test/Mesh_3/test_mesh_3_labeled_mesh_domain_3.cpp b/Mesh_3/test/Mesh_3/test_mesh_3_labeled_mesh_domain_3.cpp deleted file mode 100644 index 48cb3d4ae37..00000000000 --- a/Mesh_3/test/Mesh_3/test_mesh_3_labeled_mesh_domain_3.cpp +++ /dev/null @@ -1,271 +0,0 @@ -// Copyright (c) 2009 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// You can redistribute it and/or modify it under the terms of the GNU -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0+ -// -// -// Author(s) : Aymeric PELLE -// -//****************************************************************************** -// File Description : -//****************************************************************************** - -#define CGAL_NO_DEPRECATION_WARNINGS 1 - -#include "test_meshing_utilities.h" -#include -#include - -template -struct LM3_tester -{ - typedef typename K::Point_3 Point_3; - typedef typename K::FT FT; - - struct Function - { - typedef Point_3 Point; - typedef FT (*Func)(const Point_3&); - - Function (Func f) : f_(f) {} - FT operator() (const Point_3& p) const { return f_(p); } - - private: - Func f_; - }; - - typedef CGAL::Mesh_3::Implicit_to_labeled_function_wrapper Function_wrapper; - typedef CGAL::Mesh_3::Labeled_mesh_domain_3 Mesh_domain; - - static FT shape_function (const Point_3& p) - { - if (p.x() < 0) - return -1; - const FT x2=p.x()*p.x(), y2=p.y()*p.y(), z2=p.z()*p.z(); - return x2 + y2 + z2 - 1; - } - - static FT sphere_function (const Point_3& p) - { - const FT x2=p.x()*p.x(), y2=p.y()*p.y(), z2=p.z()*p.z(); - return x2 + y2 + z2 - 1; - } - - void operator() () const - { - typedef typename K::Sphere_3 Sphere_3; - - test_domain(Sphere_3(CGAL::ORIGIN, 4.)); - test_domain(CGAL::Bbox_3(-2.,-2.,-2., 2.,2.,2.)); - } - -private: - template - void test_domain (const BoundingShape& bounding_shape) const - { - FT error_bound(1e-3); - - Function f_sphere(&sphere_function); - Function_wrapper wrapper_1(f_sphere); - Mesh_domain domain(wrapper_1, bounding_shape, error_bound); - test_construct_initial_points(domain, error_bound); - - Function f_shape(&shape_function); - Function_wrapper wrapper_2(f_shape); - Mesh_domain domain_2(wrapper_2, bounding_shape, error_bound); - test_is_in_domain(domain_2); - test_do_intersect_surface(domain_2); - test_construct_intersection(domain_2); - } - - void test_construct_initial_points (const Mesh_domain& domain, FT error_bound) const - { - typedef typename Mesh_domain::Construct_initial_points Construct_initial_points; - typedef typename Mesh_domain::Index Index; - typedef typename std::vector >::const_iterator Points_const_iterator; - typedef typename K::Compute_squared_distance_3 Compute_squared_distance_3; - - Compute_squared_distance_3 squared_distance = K().compute_squared_distance_3_object(); - - Construct_initial_points construct_initial_points = domain.construct_initial_points_object(); - std::vector > points; - int point_count = 12; - construct_initial_points(std::back_inserter(points), point_count); - - for (Points_const_iterator iter = points.begin(), end_iter = points.end(); iter != end_iter; ++iter) - { - const Point_3& p = iter->first; - - FT sd = squared_distance(CGAL::ORIGIN, p); - FT diff = sd - 1; - if (diff < FT(0.)) - diff = -diff; - assert(diff <= error_bound); - } - } - - void test_is_in_domain (const Mesh_domain& domain) const - { - typedef typename Mesh_domain::Is_in_domain Is_in_domain; - typedef typename Mesh_domain::Subdomain Subdomain; - typedef typename Mesh_domain::Subdomain_index Subdomain_index; - - Is_in_domain is_in_domain = domain.is_in_domain_object(); - - { - Subdomain subdomain = is_in_domain(Point_3(CGAL::ORIGIN)); - assert(subdomain); - Subdomain_index subdomain_index = *subdomain; - assert(subdomain_index == 1); - } - - { - Subdomain subdomain = is_in_domain(Point_3(1.5, 0., 0.)); - assert(!subdomain); - } - } - - void test_do_intersect_surface (const Mesh_domain& domain) const - { - typedef typename Mesh_domain::Do_intersect_surface Do_intersect_surface; - typedef typename Mesh_domain::Surface_patch Surface_patch; - typedef typename Mesh_domain::Surface_patch_index Surface_patch_index; - typedef typename Mesh_domain::Segment_3 Segment_3; - typedef typename Mesh_domain::Ray_3 Ray_3; - typedef typename Mesh_domain::Line_3 Line_3; - typedef typename Mesh_domain::Vector_3 Vector_3; - - Do_intersect_surface do_intersect_surface = domain.do_intersect_surface_object(); - - { - Segment_3 s(Point_3(CGAL::ORIGIN), Point_3(1.5, 0., 0.)); - Surface_patch p = do_intersect_surface(s); - assert(p); - Surface_patch_index pi = *p; - assert(pi.first == 0 && pi.second == 1); - } - - { - Segment_3 s(Point_3(1.5, 1.5, 0.), Point_3(1.5, 0., 0.)); - Surface_patch p = do_intersect_surface(s); - assert(!p); - } - - { - Ray_3 r(Point_3(CGAL::ORIGIN), Vector_3(1., 0., 0.)); - Surface_patch p = do_intersect_surface(r); - assert(p); - Surface_patch_index pi = *p; - assert(pi.first == 0 && pi.second == 1); - } - - { - Ray_3 r(Point_3(1.5, 0., 0.), Vector_3(0., 1., 0.)); - Surface_patch p = do_intersect_surface(r); - assert(!p); - } - - { - Line_3 l(Point_3(CGAL::ORIGIN), Point_3(1.5, 0., 0.)); - Surface_patch p = do_intersect_surface(l); - assert(p); - Surface_patch_index pi = *p; - assert(pi.first == 0 && pi.second == 1); - } - - { - Line_3 l(Point_3(1.5, 0., 0.), Point_3(1.5, 0.5, 0.)); - Surface_patch p = do_intersect_surface(l); - assert(!p); - } - } - - - void test_construct_intersection (const Mesh_domain& domain) const - { - typedef typename Mesh_domain::Construct_intersection Construct_intersection; - typedef typename Mesh_domain::Intersection Intersection; - typedef typename Mesh_domain::Subdomain_index Subdomain_index; - typedef typename Mesh_domain::Surface_patch_index Surface_patch_index; - typedef typename Mesh_domain::Index Index; - typedef typename Mesh_domain::Segment_3 Segment_3; - typedef typename Mesh_domain::Ray_3 Ray_3; - typedef typename Mesh_domain::Line_3 Line_3; - typedef typename Mesh_domain::Vector_3 Vector_3; - - Construct_intersection construct_intersection = domain.construct_intersection_object(); - - { - Segment_3 s(Point_3(CGAL::ORIGIN), Point_3(1.5, 0., 0.)); - Intersection i = construct_intersection(s); - assert(CGAL::cpp11::get<0>(i) != Point_3(1., 0., 0.)); - Index ii = CGAL::cpp11::get<1>(i); - assert(boost::get(&ii)); - assert(CGAL::cpp11::get<2>(i) == 2); - } - - { - Segment_3 s(Point_3(1.5, 1.5, 0.), Point_3(1.5, 0., 0.)); - Intersection i = construct_intersection(s); - Index ii = CGAL::cpp11::get<1>(i); - assert(boost::get(&ii)); - assert(CGAL::cpp11::get<2>(i) == 0); - } - - { - Ray_3 r(Point_3(CGAL::ORIGIN), Vector_3(1., 0., 0.)); - Intersection i = construct_intersection(r); - assert(CGAL::cpp11::get<0>(i) != Point_3(1., 0., 0.)); - Index ii = CGAL::cpp11::get<1>(i); - assert(boost::get(&ii)); - assert(CGAL::cpp11::get<2>(i) == 2); - } - - { - Ray_3 r(Point_3(1.5, 0., 0.), Vector_3(0., 1., 0.)); - Intersection i = construct_intersection(r); - Index ii = CGAL::cpp11::get<1>(i); - assert(boost::get(&ii)); - assert(CGAL::cpp11::get<2>(i) == 0); - } - - { - Line_3 l(Point_3(CGAL::ORIGIN), Point_3(1.5, 0., 0.)); - Intersection i = construct_intersection(l); - assert(CGAL::cpp11::get<0>(i) != Point_3(1., 0., 0.)); - Index ii = CGAL::cpp11::get<1>(i); - assert(boost::get(&ii)); - assert(CGAL::cpp11::get<2>(i) == 2); - } - - { - Line_3 l(Point_3(1.5, 0., 0.), Point_3(1.5, 0.5, 0.)); - Intersection i = construct_intersection(l); - Index ii = CGAL::cpp11::get<1>(i); - assert(boost::get(&ii)); - assert(CGAL::cpp11::get<2>(i) == 0); - } - } -}; - - -int main () -{ - LM3_tester test_epic; - test_epic(); - - return EXIT_SUCCESS; -} diff --git a/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp b/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp index 95d39895575..bde524dbaa5 100644 --- a/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp +++ b/Mesh_3/test/Mesh_3/test_mesh_capsule_var_distance_bound.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include // Domain @@ -12,7 +12,7 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef K::FT FT; typedef K::Point_3 Point; typedef FT (Function)(const Point&); -typedef CGAL::Implicit_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; #ifdef CGAL_CONCURRENT_MESH_3 typedef CGAL::Parallel_tag Concurrency_tag; @@ -55,8 +55,9 @@ struct Field { int main() { - Mesh_domain domain(capsule_function, - K::Sphere_3(CGAL::ORIGIN, 49.)); + Mesh_domain domain = + Mesh_domain::create_implicit_mesh_domain(capsule_function, + K::Sphere_3(CGAL::ORIGIN, 49.)); // Mesh criteria Mesh_criteria criteria(facet_angle=30, facet_size=0.5, diff --git a/Mesh_3/test/Mesh_3/test_mesh_implicit_domains.cpp b/Mesh_3/test/Mesh_3/test_mesh_implicit_domains.cpp deleted file mode 100644 index f302231e0d4..00000000000 --- a/Mesh_3/test/Mesh_3/test_mesh_implicit_domains.cpp +++ /dev/null @@ -1,94 +0,0 @@ - -//****************************************************************************** -// File Description : -// Outputs to out.mesh a mesh of implicit domains. These domains are defined -// by a vector of functions. Each n-uplet of sign of function values defines a -// subdomain. -//****************************************************************************** - - -#define CGAL_NO_DEPRECATION_WARNINGS 1 - -#include "debug.h" -#include - -#include -#include -#include - -#include -#include -#include -#include "implicit_functions.h" - -// IO -#include - -using namespace CGAL::parameters; - -template -void test() -{ - // Domain - typedef CGAL::Exact_predicates_inexact_constructions_kernel K; - typedef FT_to_point_function_wrapper Function; - typedef CGAL::Mesh_3::Implicit_vector_to_labeled_function_wrapper - Function_wrapper; - typedef Function_wrapper::Function_vector Function_vector; - typedef CGAL::Mesh_3::Labeled_mesh_domain_3 Mesh_domain; - - // Triangulation - typedef typename CGAL::Mesh_triangulation_3< - Mesh_domain, - CGAL::Kernel_traits::Kernel, - Concurrency_tag>::type Tr; - typedef CGAL::Mesh_complex_3_in_triangulation_3

C3t3; - - // Mesh Criteria - typedef CGAL::Mesh_criteria_3 Mesh_criteria; - typedef typename Mesh_criteria::Facet_criteria Facet_criteria; - typedef typename Mesh_criteria::Cell_criteria Cell_criteria; - - // Define functions - Function f1(&torus_function); - Function f2(&sphere_function<5>); - Function f3(&sphere_function<2>); - - Function_vector v; - v.push_back(&f1); - v.push_back(&f2); - //v.push_back(&f3); - - // Domain (Warning: Sphere_3 constructor uses square radius !) - Mesh_domain domain(v, K::Sphere_3(CGAL::ORIGIN, 5.*5.), 1e-6); - - // Set mesh criteria - Facet_criteria facet_criteria(30, 0.2, 0.02); // angle, size, approximation - Cell_criteria cell_criteria(2., 0.4); // radius-edge ratio, size - Mesh_criteria criteria(facet_criteria, cell_criteria); - - // Mesh generation - C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, no_exude(), no_perturb()); - - // Perturbation (maximum cpu time: 10s, targeted dihedral angle: default) - CGAL::perturb_mesh_3(c3t3, domain, time_limit = 10); - - // Exudation - CGAL::exude_mesh_3(c3t3,12); - - // Output - std::ofstream medit_file("out.mesh"); - CGAL::output_to_medit(medit_file, c3t3); -} - -int main() -{ - std::cout << "==== Test sequential meshing ====" << std::endl; - test(); -#ifdef CGAL_LINKED_WITH_TBB - std::cout << "==== Test parallel meshing ====" << std::endl; - test(); -#endif - - return 0; -} diff --git a/Mesh_3/test/Mesh_3/test_mesh_polyhedral_domain_with_features_deprecated.cpp b/Mesh_3/test/Mesh_3/test_mesh_polyhedral_domain_with_features_deprecated.cpp index 05930e50d8d..5faef60a0ae 100644 --- a/Mesh_3/test/Mesh_3/test_mesh_polyhedral_domain_with_features_deprecated.cpp +++ b/Mesh_3/test/Mesh_3/test_mesh_polyhedral_domain_with_features_deprecated.cpp @@ -1,3 +1,4 @@ +#ifndef CGAL_NO_DEPRECATED_CODE #define CGAL_NO_DEPRECATION_WARNINGS #include @@ -53,3 +54,11 @@ int main() std::ofstream medit_file("out.mesh"); c3t3.output_to_medit(medit_file); } + +#else // CGAL_NO_DEPRECATED_CODE +#include +int main() { + std::cerr << "CGAL_NO_DEPRECATED_CODE is defined. Nothing to test.\n"; + return 0; +} +#endif // CGAL_NO_DEPRECATED_CODE diff --git a/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image.cpp b/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image.cpp index d1230c0ced2..1ee420467b2 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image.cpp @@ -25,7 +25,7 @@ #include "test_meshing_utilities.h" #include -#include +#include #include #include @@ -49,13 +49,8 @@ struct Image_tester : public Tester public: void image() const { - typedef float Image_word_type; typedef CGAL::Image_3 Image; - typedef CGAL::Gray_image_mesh_domain_3< - Image, - K_e_i, - Image_word_type, - Greater_than > Mesh_domain; + typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; typedef typename CGAL::Mesh_triangulation_3< Mesh_domain, @@ -78,13 +73,15 @@ public: std::cout << "\tSeed is\t" << CGAL::get_default_random().get_seed() << std::endl; - + namespace p = CGAL::parameters; // Domain - Mesh_domain domain(image, - 2.9f, //isovalue - 0.f, //value_outside - 1e-3, //error_bound - &CGAL::get_default_random());//random generator for determinism + Mesh_domain domain = + Mesh_domain::create_gray_image_mesh_domain(image, + p::iso_value = 2.9f, + p::value_outside = 0.f, + p::relative_error_bound = 1e-3, + p::p_rng = + &CGAL::get_default_random()); // Mesh criteria Mesh_criteria criteria(facet_angle = 30, diff --git a/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image_deprecated.cpp b/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image_deprecated.cpp new file mode 100644 index 00000000000..52bb90c7f2e --- /dev/null +++ b/Mesh_3/test/Mesh_3/test_meshing_3D_gray_image_deprecated.cpp @@ -0,0 +1,136 @@ +// Copyright (c) 2015 GeometryFactory (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// +// Author(s) : Laurent Rineau, Jane Tournois +// +//****************************************************************************** +// File Description : +//*************************************************************************** + +#ifndef CGAL_NO_DEPRECATED_CODE +#define CGAL_NO_DEPRECATION_WARNINGS 1 + +#include "test_meshing_utilities.h" +#include +#include +#include + +#include + +// To avoid verbose function and named parameters call +using namespace CGAL::parameters; + +template +struct Greater_than { + typedef T argument_type; + Greater_than(const T& second) : second(second) {} + bool operator()(const T& first) const { + return std::greater()(first, second); + } + T second; +}; + +template +struct Image_tester : public Tester +{ +public: + void image() const + { + typedef float Image_word_type; + typedef CGAL::Image_3 Image; + typedef CGAL::Gray_image_mesh_domain_3< + Image, + K_e_i, + Image_word_type, + Greater_than > Mesh_domain; + + typedef typename CGAL::Mesh_triangulation_3< + Mesh_domain, + CGAL::Kernel_traits::Kernel, + Concurrency_tag>::type Tr; + typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; + typedef CGAL::Mesh_criteria_3 Mesh_criteria; + + CGAL_USE_TYPE(typename Mesh_domain::Surface_patch_index); + + //------------------------------------------------------- + // Data generation + //------------------------------------------------------- + Image image; + if (!image.read("data/skull_2.9.inr")) + { + std::cout << "Image reading error. Exit test.\n"; + return; + } + + std::cout << "\tSeed is\t" + << CGAL::get_default_random().get_seed() << std::endl; + + // Domain + Mesh_domain domain(image, + 2.9f, //isovalue + 0.f, //value_outside + 1e-3, //error_bound + &CGAL::get_default_random());//random generator for determinism + + // Mesh criteria + Mesh_criteria criteria(facet_angle = 30, + facet_size = 6, + facet_distance = 2, + facet_topology = CGAL::MANIFOLD, + cell_radius_edge_ratio = 3, + cell_size = 8); + + // Mesh generation + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, + no_perturb(), + no_exude(), + mesh_3_options(number_of_initial_points = 30), + non_manifold() + ); + + // Verify + this->verify_c3t3_volume(c3t3, 1236086 * 0.95, 1236086 * 1.05); + this->verify(c3t3, domain, criteria, Bissection_tag()); + } +}; + + +int main() +{ + Image_tester<> test_epic; + std::cerr << "Mesh generation from a 3D image:\n"; + test_epic.image(); + +#ifdef CGAL_LINKED_WITH_TBB + Image_tester test_epic_p; + std::cerr << "Parallel mesh generation from a 3D image:\n"; + test_epic_p.image(); +#endif + + return EXIT_SUCCESS; +} + +#else // CGAL_NO_DEPRECATED_CODE +#include +int main() { + std::cerr << "CGAL_NO_DEPRECATED_CODE is defined. Nothing to test.\n"; + return 0; +} +#endif // CGAL_NO_DEPRECATED_CODE diff --git a/Mesh_3/test/Mesh_3/test_meshing_3D_image.cpp b/Mesh_3/test/Mesh_3/test_meshing_3D_image.cpp index 1b3a846c39a..c80ecd2e86d 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_3D_image.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_3D_image.cpp @@ -25,7 +25,7 @@ #include "test_meshing_utilities.h" #include -#include +#include #include template @@ -35,7 +35,7 @@ public: void image() const { typedef CGAL::Image_3 Image; - typedef CGAL::Labeled_image_mesh_domain_3 Mesh_domain; + typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; typedef typename CGAL::Mesh_triangulation_3< Mesh_domain, @@ -55,7 +55,10 @@ public: std::cout << "\tSeed is\t" << CGAL::get_default_random().get_seed() << std::endl; - Mesh_domain domain(image, 1e-9, &CGAL::get_default_random()); + Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain + (image, + 1e-9, + CGAL::parameters::p_rng = &CGAL::get_default_random()); // Set mesh criteria Facet_criteria facet_criteria(25, 20*image.vx(), 5*image.vx()); diff --git a/Mesh_3/test/Mesh_3/test_meshing_3D_image_deprecated.cpp b/Mesh_3/test/Mesh_3/test_meshing_3D_image_deprecated.cpp new file mode 100644 index 00000000000..7beb6765bb1 --- /dev/null +++ b/Mesh_3/test/Mesh_3/test_meshing_3D_image_deprecated.cpp @@ -0,0 +1,107 @@ +// Copyright (c) 2009 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// +// Author(s) : Stephane Tayeb +// +//****************************************************************************** +// File Description : +//****************************************************************************** + +#ifndef CGAL_NO_DEPRECATED_CODE +#define CGAL_NO_DEPRECATION_WARNINGS 1 + +#include "test_meshing_utilities.h" +#include +#include +#include + +template +struct Image_tester : public Tester +{ +public: + void image() const + { + typedef CGAL::Image_3 Image; + typedef CGAL::Labeled_image_mesh_domain_3 Mesh_domain; + + typedef typename CGAL::Mesh_triangulation_3< + Mesh_domain, + CGAL::Kernel_traits::Kernel, + Concurrency_tag>::type Tr; + typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; + + typedef CGAL::Mesh_criteria_3 Mesh_criteria; + typedef typename Mesh_criteria::Facet_criteria Facet_criteria; + typedef typename Mesh_criteria::Cell_criteria Cell_criteria; + + //------------------------------------------------------- + // Data generation + //------------------------------------------------------- + Image image; + image.read("data/liver.inr.gz"); + + std::cout << "\tSeed is\t" + << CGAL::get_default_random().get_seed() << std::endl; + Mesh_domain domain(image, 1e-9, &CGAL::get_default_random()); + + // Set mesh criteria + Facet_criteria facet_criteria(25, 20*image.vx(), 5*image.vx()); + Cell_criteria cell_criteria(4, 25*image.vx()); + Mesh_criteria criteria(facet_criteria, cell_criteria); + + // Mesh generation + C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, + CGAL::parameters::no_exude(), + CGAL::parameters::no_perturb()); + + // Verify + this->verify_c3t3_volume(c3t3, 1772330*0.95, 1772330*1.05); + this->verify(c3t3,domain,criteria, Bissection_tag()); + + typedef typename Mesh_domain::Surface_patch_index Patch_id; + CGAL_static_assertion(CGAL::Output_rep::is_specialized); + CGAL_USE_TYPE(Patch_id); + } + +}; + + + +int main() +{ + Image_tester<> test_epic; + std::cerr << "Mesh generation from a 3D image:\n"; + test_epic.image(); + +#ifdef CGAL_LINKED_WITH_TBB + Image_tester test_epic_p; + std::cerr << "Parallel mesh generation from a 3D image:\n"; + test_epic_p.image(); +#endif + + return EXIT_SUCCESS; +} + +#else // CGAL_NO_DEPRECATED_CODE +#include +int main() { + std::cerr << "CGAL_NO_DEPRECATED_CODE is defined. Nothing to test.\n"; + return 0; +} +#endif // CGAL_NO_DEPRECATED_CODE diff --git a/Mesh_3/test/Mesh_3/test_meshing_implicit_function.cpp b/Mesh_3/test/Mesh_3/test_meshing_implicit_function.cpp index 28ce9021278..ec8effb5f4a 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_implicit_function.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_implicit_function.cpp @@ -24,7 +24,7 @@ //****************************************************************************** #include "test_meshing_utilities.h" -#include +#include #include @@ -42,9 +42,7 @@ struct Implicit_tester : public Tester void implicit() const { - typedef FT (Function)(const Point&); - - typedef CGAL::Implicit_mesh_domain_3 Mesh_domain; + typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; typedef typename CGAL::Mesh_triangulation_3< Mesh_domain, @@ -65,10 +63,14 @@ struct Implicit_tester : public Tester //------------------------------------------------------- std::cout << "\tSeed is\t" << CGAL::get_default_random().get_seed() << std::endl; - Mesh_domain domain(Implicit_tester::sphere_function, - Sphere_3(CGAL::ORIGIN,2.), - 1e-3, - &CGAL::get_default_random()); + + namespace p = CGAL::parameters; + Mesh_domain domain = + Mesh_domain::create_implicit_mesh_domain + (p::function = Implicit_tester::sphere_function, + p::bounding_object = Sphere_3(CGAL::ORIGIN,2.), + p::p_rng = &CGAL::get_default_random(), + p::relative_error_bound = 1e-3); // Set mesh criteria Facet_criteria facet_criteria(0, 0, 0.3); diff --git a/Mesh_3/test/Mesh_3/test_meshing_polyhedron_with_features.cpp b/Mesh_3/test/Mesh_3/test_meshing_polyhedron_with_features.cpp index 248a1b651db..67d58f98179 100644 --- a/Mesh_3/test/Mesh_3/test_meshing_polyhedron_with_features.cpp +++ b/Mesh_3/test/Mesh_3/test_meshing_polyhedron_with_features.cpp @@ -72,13 +72,20 @@ struct Polyhedron_with_features_tester : public Tester CGAL_USE(polyhedra); // Set mesh criteria +#ifndef CGAL_MESH_3_VERBOSE Edge_criteria edge_criteria(0.2); Facet_criteria facet_criteria(30, 0.2, 0.02); Cell_criteria cell_criteria(3, 0.2); +#else // a different set of criteria, for the test of CGAL_MESH_3_VERBOSE + Edge_criteria edge_criteria(0.3); + Facet_criteria facet_criteria(30, 0.3, 0.03); + Cell_criteria cell_criteria(3, 0.4); +#endif Mesh_criteria criteria(edge_criteria, facet_criteria, cell_criteria); // Mesh generation C3t3 c3t3 = CGAL::make_mesh_3(domain, criteria, + CGAL::parameters::manifold(), CGAL::parameters::no_exude(), CGAL::parameters::no_perturb()); diff --git a/Mesh_3/test/Mesh_3/test_meshing_verbose.cpp b/Mesh_3/test/Mesh_3/test_meshing_verbose.cpp new file mode 100644 index 00000000000..59a96e24ba1 --- /dev/null +++ b/Mesh_3/test/Mesh_3/test_meshing_verbose.cpp @@ -0,0 +1,5 @@ +#define CGAL_MESH_3_VERBOSE 1 +#include "test_meshing_polyhedron_with_features.cpp" + +// This comment is for the shell script cgal_test +// int main() { return 0; } diff --git a/Mesh_3/test/Mesh_3/test_meshing_with_one_step.cpp b/Mesh_3/test/Mesh_3/test_meshing_with_one_step.cpp new file mode 100644 index 00000000000..cdc18b0888c --- /dev/null +++ b/Mesh_3/test/Mesh_3/test_meshing_with_one_step.cpp @@ -0,0 +1,78 @@ +#define CGAL_MESH_3_VERBOSE 1 +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +// Domain +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Surface_mesh Polyhedron; +typedef CGAL::Polyhedral_mesh_domain_3 Mesh_domain; + +typedef CGAL::Sequential_tag Concurrency_tag; + +// Triangulation +typedef CGAL::Mesh_triangulation_3::type Tr; + +typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; + +// Criteria +typedef CGAL::Mesh_criteria_3 Mesh_criteria; + +typedef CGAL::Mesh_3::Mesher_3 Mesher; + +// To avoid verbose function and named parameters call +using namespace CGAL::parameters; + +int main(int argc, char*argv[]) +{ + const char* fname = (argc>1)?argv[1]:"data/sphere.off"; + // Create input polyhedron + Polyhedron polyhedron; + std::ifstream input(fname); + input >> polyhedron; + if(input.fail()){ + std::cerr << "Error: Cannot read file " << fname << std::endl; + return EXIT_FAILURE; + } + input.close(); + + if (!CGAL::is_triangle_mesh(polyhedron)){ + std::cerr << "Input geometry is not triangulated." << std::endl; + return EXIT_FAILURE; + } + + // Create domain + Mesh_domain domain(polyhedron); + + // Mesh criteria (no cell_size set) + Mesh_criteria criteria(facet_angle=25, facet_size=0.2, facet_distance=0.01, + cell_size = 0.2, cell_radius_edge_ratio=3); + + // Mesh generation + C3t3 c3t3; + CGAL::internal::Mesh_3::C3t3_initializer()(c3t3, domain, criteria, false); + Mesher mesher(c3t3, domain, criteria,CGAL::FACET_VERTICES_ON_SAME_SURFACE_PATCH); + mesher.initialize(); + while ( ! mesher.is_algorithm_done() ) mesher.one_step(); + assert(c3t3.triangulation().number_of_vertices() > 200); + // Output + std::ofstream medit_file("out.mesh"); + c3t3.output_to_medit(medit_file); + medit_file.close(); + + return EXIT_SUCCESS; +} diff --git a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/AABB_traits_2.h b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/AABB_traits_2.h index 7088fd1b83d..1eb99e9e72a 100644 --- a/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/AABB_traits_2.h +++ b/Minkowski_sum_2/include/CGAL/Minkowski_sum_2/AABB_traits_2.h @@ -102,11 +102,11 @@ public: if (bbox.xmax()-bbox.xmin() >= bbox.ymax()-bbox.ymin()) { - std::nth_element(first, middle, beyond, less_x); // sort along x + std::nth_element(first, middle, beyond, AABB_traits_2::less_x); // sort along x } else { - std::nth_element(first, middle, beyond, less_y); // sort along y + std::nth_element(first, middle, beyond, AABB_traits_2::less_y); // sort along y } } }; diff --git a/Minkowski_sum_2/test/Minkowski_sum_2/CMakeLists.txt b/Minkowski_sum_2/test/Minkowski_sum_2/CMakeLists.txt index 5ec0bc17e3b..e41e969753f 100644 --- a/Minkowski_sum_2/test/Minkowski_sum_2/CMakeLists.txt +++ b/Minkowski_sum_2/test/Minkowski_sum_2/CMakeLists.txt @@ -6,15 +6,16 @@ project( Minkowski_sum_2_Tests ) cmake_minimum_required(VERSION 2.8.10) -list(FIND CMAKE_CXX_COMPILE_FEATURES cxx_generalized_initializers has_cpp11) -if (has_cpp11 LESS 0) - message(STATUS "NOTICE: These examples requires a C++11 compiler and will not be compiled.") - return() -endif() +# Commented out C++11 for now +# list(FIND CMAKE_CXX_COMPILE_FEATURES cxx_generalized_initializers has_cpp11) +# if (has_cpp11 LESS 0) +# message(STATUS "NOTICE: These examples requires a C++11 compiler and will not be compiled.") +# return() +# endif() -# Use C++11 for this directory and its sub-directories. -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED TRUE) +# # Use C++11 for this directory and its sub-directories. +# set(CMAKE_CXX_STANDARD 11) +# set(CMAKE_CXX_STANDARD_REQUIRED TRUE) find_package(CGAL QUIET COMPONENTS Core ) diff --git a/Nef_2/include/CGAL/Nef_polynomial.h b/Nef_2/include/CGAL/Nef_polynomial.h index ee252bd9a17..3d546ddd24b 100644 --- a/Nef_2/include/CGAL/Nef_polynomial.h +++ b/Nef_2/include/CGAL/Nef_polynomial.h @@ -146,7 +146,7 @@ public: typedef typename AST_NT::Is_exact Is_exact; typedef Tag_false Is_numerical_sensitive; class Integral_division - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, @@ -158,7 +158,7 @@ public: }; class Gcd - : public CGAL::binary_function< Type, Type, Type > { + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, const Type& y ) const { // By definition gcd(0,0) == 0 @@ -176,7 +176,7 @@ template class Real_embeddable_traits< Nef_polynomial > public: typedef Nef_polynomial Type; class Abs - : public CGAL::unary_function< Type, Type> { + : public CGAL::cpp98::unary_function< Type, Type> { public: Type inline operator()( const Type& x ) const { return (CGAL::Nef::sign( x ) == CGAL::NEGATIVE)? -x : x; @@ -184,7 +184,7 @@ template class Real_embeddable_traits< Nef_polynomial > }; class Sgn - : public CGAL::unary_function< Type, CGAL::Sign > { + : public CGAL::cpp98::unary_function< Type, CGAL::Sign > { public: CGAL::Sign inline operator()( const Type& x ) const { return CGAL::Nef::sign( x ); @@ -192,7 +192,7 @@ template class Real_embeddable_traits< Nef_polynomial > }; class Compare - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, CGAL::Comparison_result > { public: CGAL::Comparison_result inline operator()( @@ -203,7 +203,7 @@ template class Real_embeddable_traits< Nef_polynomial > }; class To_double - : public CGAL::unary_function< Type, double > { + : public CGAL::cpp98::unary_function< Type, double > { public: double inline operator()( const Type& p ) const { return CGAL::to_double( @@ -212,7 +212,7 @@ template class Real_embeddable_traits< Nef_polynomial > }; class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& p ) const { return CGAL::to_interval(p.eval_at(Nef_polynomial::infi_maximal_value())); diff --git a/Nef_3/examples/Nef_3/handling_double_coordinates.cpp b/Nef_3/examples/Nef_3/handling_double_coordinates.cpp index 7f194599b50..9a570ef0599 100644 --- a/Nef_3/examples/Nef_3/handling_double_coordinates.cpp +++ b/Nef_3/examples/Nef_3/handling_double_coordinates.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include diff --git a/Nef_3/examples/Nef_3/interface_polyhedron.cpp b/Nef_3/examples/Nef_3/interface_polyhedron.cpp index ab6b36ca7a6..6cd007b3a0b 100644 --- a/Nef_3/examples/Nef_3/interface_polyhedron.cpp +++ b/Nef_3/examples/Nef_3/interface_polyhedron.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include #include diff --git a/Nef_3/examples/Nef_3/offIO.cpp b/Nef_3/examples/Nef_3/offIO.cpp index 94f69d586fc..ffc0fa34b24 100644 --- a/Nef_3/examples/Nef_3/offIO.cpp +++ b/Nef_3/examples/Nef_3/offIO.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include #include diff --git a/Nef_3/test/Nef_3/nef_union_error_llvm.cpp b/Nef_3/test/Nef_3/nef_union_error_llvm.cpp index bca9fec0243..d0683165374 100644 --- a/Nef_3/test/Nef_3/nef_union_error_llvm.cpp +++ b/Nef_3/test/Nef_3/nef_union_error_llvm.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include #include diff --git a/Nef_S2/include/CGAL/Nef_S2/leda_sphere_map.h b/Nef_S2/include/CGAL/Nef_S2/leda_sphere_map.h index 74e07af9bd1..c95468bb54b 100644 --- a/Nef_S2/include/CGAL/Nef_S2/leda_sphere_map.h +++ b/Nef_S2/include/CGAL/Nef_S2/leda_sphere_map.h @@ -247,7 +247,7 @@ void compute_faces() } void dump(std::ostream& os, leda_node v, bool nl=true) const -{ os << " ["<<::index(v)<<"] "< struct Point_of_sphere : private Store_kernel { typedef Point result_type; typedef Sphere first_argument_type; typedef int second_argument_type; - struct Trans : CGAL::binary_function { + struct Trans : CGAL::cpp98::binary_function { FT const& r_; int idx; bool sgn; Trans (int n, FT const& r, bool b) : r_(r), idx(n), sgn(b) {} FT operator()(FT const&x, int i)const{ diff --git a/NewKernel_d/include/CGAL/NewKernel_d/function_objects_cartesian.h b/NewKernel_d/include/CGAL/NewKernel_d/function_objects_cartesian.h index 58a8ba3fe56..1e7a34b3e1e 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/function_objects_cartesian.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/function_objects_cartesian.h @@ -1033,7 +1033,7 @@ template struct Midpoint : private Store_kernel { typedef Point first_argument_type; typedef Point second_argument_type; // There is a division, but it will be cast to RT afterwards anyway, so maybe we could use RT. - struct Average : CGAL::binary_function { + struct Average : CGAL::cpp98::binary_function { FT operator()(FT const&a, RT const&b)const{ return (a+b)/2; } @@ -1099,7 +1099,7 @@ template struct Squared_distance : private Store_kernel { typedef RT result_type; typedef Point first_argument_type; typedef Point second_argument_type; - struct Sq_diff : CGAL::binary_function { + struct Sq_diff : CGAL::cpp98::binary_function { RT operator()(RT const&a, RT const&b)const{ return CGAL::square(a-b); } diff --git a/Number_types/include/CGAL/CORE_BigFloat.h b/Number_types/include/CGAL/CORE_BigFloat.h index 652e2d840ec..7f7d430e39f 100644 --- a/Number_types/include/CGAL/CORE_BigFloat.h +++ b/Number_types/include/CGAL/CORE_BigFloat.h @@ -46,7 +46,7 @@ public: typedef CGAL::Tag_true Is_bigfloat_interval; - struct Lower :public CGAL::unary_function{ + struct Lower :public CGAL::cpp98::unary_function{ Bound operator() ( Interval x ) const { CORE::BigFloat result = ::CORE::BigFloat(x.m()-x.err(),0,x.exp()); CGAL_postcondition(result <= x); @@ -54,7 +54,7 @@ public: } }; - struct Upper :public CGAL::unary_function{ + struct Upper :public CGAL::cpp98::unary_function{ Bound operator() ( Interval x ) const { CORE::BigFloat result = ::CORE::BigFloat(x.m()+x.err(),0,x.exp()); CGAL_postcondition(result >= x); @@ -62,7 +62,7 @@ public: } }; - struct Width :public CGAL::unary_function{ + struct Width :public CGAL::cpp98::unary_function{ Bound operator() ( Interval x ) const { unsigned long err = 2*x.err(); @@ -70,52 +70,52 @@ public: } }; - struct Median :public CGAL::unary_function{ + struct Median :public CGAL::cpp98::unary_function{ Bound operator() ( Interval x ) const { return Bound(x.m(),0,x.exp()); } }; - struct Norm :public CGAL::unary_function{ + struct Norm :public CGAL::cpp98::unary_function{ Bound operator() ( Interval x ) const { BOOST_USING_STD_MAX(); return max BOOST_PREVENT_MACRO_SUBSTITUTION (Upper()(x).abs(),Lower()(x).abs()); } }; - struct Zero_in :public CGAL::unary_function{ + struct Zero_in :public CGAL::cpp98::unary_function{ bool operator() ( Interval x ) const { return x.isZeroIn(); } }; - struct In :public CGAL::binary_function{ + struct In :public CGAL::cpp98::binary_function{ bool operator()( Bound x, const Interval& a ) const { CGAL_precondition(CGAL::singleton(x)); return (Lower()(a) <= x && x <= Upper()(a)); } }; - struct Equal :public CGAL::binary_function{ + struct Equal :public CGAL::cpp98::binary_function{ bool operator()( const Interval& a, const Interval& b ) const { return (Upper()(a) == Upper()(b) && Lower()(a) == Lower()(b)); } }; - struct Subset :public CGAL::binary_function{ + struct Subset :public CGAL::cpp98::binary_function{ bool operator()( const Interval& a, const Interval& b ) const { return Lower()(b) <= Lower()(a) && Upper()(a) <= Upper()(b); } }; - struct Proper_subset :public CGAL::binary_function{ + struct Proper_subset :public CGAL::cpp98::binary_function{ bool operator()( const Interval& a, const Interval& b ) const { return Subset()(a,b) && (!Equal()(a,b)); } }; - struct Intersection :public CGAL::binary_function{ + struct Intersection :public CGAL::cpp98::binary_function{ Interval operator()( const Interval& a, const Interval& b ) const { BOOST_USING_STD_MAX(); BOOST_USING_STD_MIN(); @@ -129,7 +129,7 @@ public: }; - struct Overlap :public CGAL::binary_function{ + struct Overlap :public CGAL::cpp98::binary_function{ bool operator() ( Interval x, Interval y ) const { Self::Zero_in Zero_in; bool result = Zero_in(x-y); @@ -137,7 +137,7 @@ public: } }; - struct Hull :public CGAL::binary_function{ + struct Hull :public CGAL::cpp98::binary_function{ // for debugging /* void print_bf(CORE::BigFloat bf, std::string s) const { @@ -229,13 +229,13 @@ public: } }; - struct Singleton :public CGAL::unary_function { + struct Singleton :public CGAL::cpp98::unary_function { bool operator() ( Interval x ) const { return (x.err() == 0); } }; - struct Construct :public CGAL::binary_function{ + struct Construct :public CGAL::cpp98::binary_function{ Interval operator()( const Bound& l,const Bound& r) const { CGAL_precondition( l < r ); return Hull()(l,r); @@ -376,7 +376,7 @@ template <> class Algebraic_structure_traits< CORE::BigFloat > typedef Tag_true Is_numerical_sensitive; class Sqrt - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { // What I want is a sqrt computed with @@ -406,7 +406,7 @@ template <> class Algebraic_structure_traits< CORE::BigFloat > }; class Kth_root - : public CGAL::binary_function { + : public CGAL::cpp98::binary_function { public: Type operator()( int k, const Type& x) const { @@ -429,7 +429,7 @@ template <> class Real_embeddable_traits< CORE::BigFloat > : public INTERN_RET::Real_embeddable_traits_base< CORE::BigFloat , CGAL::Tag_true > { public: class Abs - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { Type result; @@ -462,7 +462,7 @@ template <> class Real_embeddable_traits< CORE::BigFloat > }; class Sgn - : public CGAL::unary_function< Type, ::CGAL::Sign > { + : public CGAL::cpp98::unary_function< Type, ::CGAL::Sign > { public: ::CGAL::Sign operator()( const Type& x ) const { ::CGAL::Sign result = sign( x.sign()); @@ -471,7 +471,7 @@ template <> class Real_embeddable_traits< CORE::BigFloat > }; class Compare - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Comparison_result > { public: Comparison_result operator()( const Type& x, @@ -483,7 +483,7 @@ template <> class Real_embeddable_traits< CORE::BigFloat > }; class To_double - : public CGAL::unary_function< Type, double > { + : public CGAL::cpp98::unary_function< Type, double > { public: double operator()( const Type& x ) const { // this call is required to get reasonable values for the double @@ -493,7 +493,7 @@ template <> class Real_embeddable_traits< CORE::BigFloat > }; class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { diff --git a/Number_types/include/CGAL/CORE_BigInt.h b/Number_types/include/CGAL/CORE_BigInt.h index 44a3472ea67..7e98810f393 100644 --- a/Number_types/include/CGAL/CORE_BigInt.h +++ b/Number_types/include/CGAL/CORE_BigInt.h @@ -53,7 +53,7 @@ template <> class Algebraic_structure_traits< CORE::BigInt > typedef INTERN_AST::Mod_per_operator< Type > Mod; class Sqrt - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: //! computes the largest NT not larger than the square root of \a a. Type operator()( const Type& x) const { @@ -65,7 +65,7 @@ template <> class Algebraic_structure_traits< CORE::BigInt > class Gcd - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, @@ -88,7 +88,7 @@ template <> class Real_embeddable_traits< CORE::BigInt > public: class Abs - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return CORE::abs( x ); @@ -96,7 +96,7 @@ template <> class Real_embeddable_traits< CORE::BigInt > }; class Sgn - : public CGAL::unary_function< Type, ::CGAL::Sign > { + : public CGAL::cpp98::unary_function< Type, ::CGAL::Sign > { public: ::CGAL::Sign operator()( const Type& x ) const { return (::CGAL::Sign) CORE::sign( x ); @@ -104,7 +104,7 @@ template <> class Real_embeddable_traits< CORE::BigInt > }; class Compare - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Comparison_result > { public: Comparison_result operator()( const Type& x, @@ -114,7 +114,7 @@ template <> class Real_embeddable_traits< CORE::BigInt > }; class To_double - : public CGAL::unary_function< Type, double > { + : public CGAL::cpp98::unary_function< Type, double > { public: double operator()( const Type& x ) const { // this call is required to get reasonable values for the double @@ -124,7 +124,7 @@ template <> class Real_embeddable_traits< CORE::BigInt > }; class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x_ ) const { CORE::Expr x(x_); diff --git a/Number_types/include/CGAL/CORE_BigRat.h b/Number_types/include/CGAL/CORE_BigRat.h index 0d0dd010f66..51607d2b982 100644 --- a/Number_types/include/CGAL/CORE_BigRat.h +++ b/Number_types/include/CGAL/CORE_BigRat.h @@ -67,7 +67,7 @@ template <> class Real_embeddable_traits< CORE::BigRat > public: class Abs - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return CORE::abs( x ); @@ -75,7 +75,7 @@ template <> class Real_embeddable_traits< CORE::BigRat > }; class Sgn - : public CGAL::unary_function< Type, ::CGAL::Sign > { + : public CGAL::cpp98::unary_function< Type, ::CGAL::Sign > { public: ::CGAL::Sign operator()( const Type& x ) const { return (::CGAL::Sign) CORE::sign( x ); @@ -83,7 +83,7 @@ template <> class Real_embeddable_traits< CORE::BigRat > }; class Compare - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Comparison_result > { public: Comparison_result operator()( const Type& x, @@ -94,7 +94,7 @@ template <> class Real_embeddable_traits< CORE::BigRat > }; class To_double - : public CGAL::unary_function< Type, double > { + : public CGAL::cpp98::unary_function< Type, double > { public: double operator()( const Type& x ) const { // this call is required to get reasonable values for the double @@ -104,7 +104,7 @@ template <> class Real_embeddable_traits< CORE::BigRat > }; class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x_ ) const { CORE::Expr x(x_); diff --git a/Number_types/include/CGAL/CORE_Expr.h b/Number_types/include/CGAL/CORE_Expr.h index a815bc87195..ad194565715 100644 --- a/Number_types/include/CGAL/CORE_Expr.h +++ b/Number_types/include/CGAL/CORE_Expr.h @@ -44,7 +44,7 @@ template <> class Algebraic_structure_traits< CORE::Expr > typedef Tag_true Is_numerical_sensitive; class Sqrt - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return CORE::sqrt( x ); @@ -52,7 +52,7 @@ template <> class Algebraic_structure_traits< CORE::Expr > }; class Kth_root - : public CGAL::binary_function { + : public CGAL::cpp98::binary_function { public: Type operator()( int k, const Type& x) const { @@ -131,7 +131,7 @@ template <> class Real_embeddable_traits< CORE::Expr > : public INTERN_RET::Real_embeddable_traits_base< CORE::Expr , CGAL::Tag_true > { public: class Abs - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return CORE::abs( x ); @@ -139,7 +139,7 @@ template <> class Real_embeddable_traits< CORE::Expr > }; class Sgn - : public CGAL::unary_function< Type, ::CGAL::Sign > { + : public CGAL::cpp98::unary_function< Type, ::CGAL::Sign > { public: ::CGAL::Sign operator()( const Type& x ) const { return (::CGAL::Sign) CORE::sign( x ); @@ -147,7 +147,7 @@ template <> class Real_embeddable_traits< CORE::Expr > }; class Compare - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Comparison_result > { public: Comparison_result operator()( const Type& x, @@ -161,7 +161,7 @@ template <> class Real_embeddable_traits< CORE::Expr > }; class To_double - : public CGAL::unary_function< Type, double > { + : public CGAL::cpp98::unary_function< Type, double > { public: double operator()( const Type& x ) const { x.approx(53,1075); @@ -170,7 +170,7 @@ template <> class Real_embeddable_traits< CORE::Expr > }; class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { std::pair result; diff --git a/Number_types/include/CGAL/Counted_number.h b/Number_types/include/CGAL/Counted_number.h index 22c9b009400..1ceae4c92e1 100644 --- a/Number_types/include/CGAL/Counted_number.h +++ b/Number_types/include/CGAL/Counted_number.h @@ -445,7 +445,7 @@ operator>=(Counted_number const &n1, Counted_number const &n2) template class Is_valid< Counted_number > - : public CGAL::unary_function< Counted_number, bool > { + : public CGAL::cpp98::unary_function< Counted_number, bool > { public: bool operator()( const Counted_number& x ) { return is_valid( x.rep() ); @@ -515,7 +515,7 @@ namespace INTERN_COUNTED_NUMBER{ template< class NT, class Functor > struct Simplify_selector { - struct Simplify : public CGAL::unary_function { + struct Simplify : public CGAL::cpp98::unary_function { void operator()( NT& x ) const { x.simplify(); } @@ -529,7 +529,7 @@ struct Simplify_selector< NT, Null_functor > { template< class NT, class Functor > struct Unit_part_selector { - struct Unit_part : public CGAL::unary_function { + struct Unit_part : public CGAL::cpp98::unary_function { NT operator()( const NT& x ) const { return x.unit_part(); } @@ -543,7 +543,7 @@ struct Unit_part_selector< NT, Null_functor > { template< class NT, class Functor > struct Is_zero_selector { - struct Is_zero : public CGAL::unary_function { + struct Is_zero : public CGAL::cpp98::unary_function { bool operator()( const NT& x ) const { return x.is_zero(); } @@ -557,7 +557,7 @@ struct Is_zero_selector< NT, Null_functor > { template< class NT, class Functor > struct Is_one_selector { - struct Is_one : public CGAL::unary_function { + struct Is_one : public CGAL::cpp98::unary_function { bool operator()( const NT& x ) const { return x.is_one(); } @@ -571,7 +571,7 @@ struct Is_one_selector< NT, Null_functor > { template< class NT, class Functor > struct Square_selector { - struct Square : public CGAL::unary_function { + struct Square : public CGAL::cpp98::unary_function { NT operator()( const NT& x ) const { return x.square(); } @@ -585,7 +585,7 @@ struct Square_selector< NT, Null_functor > { template< class NT, class Functor > struct Integral_division_selector { - struct Integral_division : public CGAL::binary_function { + struct Integral_division : public CGAL::cpp98::binary_function { NT operator()( const NT& x, const NT& y ) const { return x.integral_division( y ); } @@ -599,7 +599,7 @@ struct Integral_division_selector< NT, Null_functor > { template< class NT, class Functor > struct Is_square_selector { - struct Is_square : public CGAL::binary_function { + struct Is_square : public CGAL::cpp98::binary_function { bool operator()( const NT& x, NT& y ) const { return x.is_square( y ); } @@ -618,7 +618,7 @@ struct Is_square_selector< NT, Null_functor > { template struct Sqrt_selector{ - struct Sqrt : public CGAL::unary_function { + struct Sqrt : public CGAL::cpp98::unary_function { NT operator ()(const NT& x) const { return x.sqrt(); } @@ -631,7 +631,7 @@ struct Sqrt_selector { template< class NT, class Functor > struct Kth_root_selector { - struct Kth_root : public CGAL::binary_function { + struct Kth_root : public CGAL::cpp98::binary_function { NT operator()( int k, const NT& x ) const { return x.kth_root( k ); } @@ -687,7 +687,7 @@ struct Root_of_selector< NT, Null_functor > { template< class NT, class Functor > struct Gcd_selector { - struct Gcd : public CGAL::binary_function { + struct Gcd : public CGAL::cpp98::binary_function { NT operator()( const NT& x, const NT& y ) const { return x.gcd( y ); } @@ -701,7 +701,7 @@ struct Gcd_selector< NT, Null_functor > { template< class NT, class Functor > struct Div_selector { - struct Div : public CGAL::binary_function { + struct Div : public CGAL::cpp98::binary_function { NT operator()( const NT& x, const NT& y ) const { return x.div( y ); } @@ -715,7 +715,7 @@ struct Div_selector< NT, Null_functor > { template< class NT, class Functor > struct Mod_selector { - struct Mod : public CGAL::binary_function { + struct Mod : public CGAL::cpp98::binary_function { NT operator()( const NT& x, const NT& y ) const { return x.mod( y ); } @@ -818,20 +818,20 @@ public: , typename RET_NT::Is_zero > ::Is_zero Is_zero; class Is_finite - : public CGAL::unary_function< Counted_number, bool > { + : public CGAL::cpp98::unary_function< Counted_number, bool > { public: bool operator()( const Counted_number& x ) const { return CGAL_NTS is_finite( x.rep() ); } }; - struct To_double : public CGAL::unary_function< Counted_number, double > { + struct To_double : public CGAL::cpp98::unary_function< Counted_number, double > { double operator()(const Counted_number& x) const { return x.to_double(); } }; - struct To_interval: public CGAL::unary_function< Counted_number, std::pair > { + struct To_interval: public CGAL::cpp98::unary_function< Counted_number, std::pair > { std::pair operator()(const Counted_number& x) const { return x.to_interval(); diff --git a/Number_types/include/CGAL/Gmpfi.h b/Number_types/include/CGAL/Gmpfi.h index 602a079c44a..90bd854fe9b 100644 --- a/Number_types/include/CGAL/Gmpfi.h +++ b/Number_types/include/CGAL/Gmpfi.h @@ -42,28 +42,28 @@ public: typedef Uncertain Boolean; struct Is_zero: - public CGAL::unary_function{ + public CGAL::cpp98::unary_function{ Boolean operator()(const Type &x)const{ return x.is_zero(); } }; struct Is_one: - public CGAL::unary_function{ + public CGAL::cpp98::unary_function{ Boolean operator()(const Type &x)const{ return x.is_one(); } }; struct Square: - public CGAL::unary_function{ + public CGAL::cpp98::unary_function{ Type operator()(const Type &x)const{ return x.square(); }; }; struct Is_square: - public CGAL::binary_function{ + public CGAL::cpp98::binary_function{ Boolean operator()(const Type &x)const{ return x.is_square(); }; @@ -73,21 +73,21 @@ public: }; struct Sqrt: - public CGAL::unary_function{ + public CGAL::cpp98::unary_function{ Type operator()(const Type &x)const{ return x.sqrt(); }; }; struct Kth_Root: - public CGAL::binary_function{ + public CGAL::cpp98::binary_function{ Type operator()(int k,const Type &x)const{ return (k==3?x.cbrt():x.kthroot(k)); }; }; struct Divides: - public CGAL::binary_function{ + public CGAL::cpp98::binary_function{ Boolean operator()(const Type &d,const Type &n)const{ // Avoid compiler warning (void)n; @@ -115,42 +115,42 @@ public INTERN_RET::Real_embeddable_traits_base{ typedef AST::Is_zero Is_zero; struct Is_finite: - public CGAL::unary_function{ + public CGAL::cpp98::unary_function{ inline Boolean operator()(const Type &x)const{ return(x.is_number()); }; }; struct Abs: - public CGAL::unary_function{ + public CGAL::cpp98::unary_function{ inline Type operator()(const Type &x)const{ return x.abs(); }; }; struct Sgn: - public CGAL::unary_function{ + public CGAL::cpp98::unary_function{ inline Sign operator()(const Type &x)const{ return x.sign(); }; }; struct Is_positive: - public CGAL::unary_function{ + public CGAL::cpp98::unary_function{ inline Boolean operator()(const Type &x)const{ return x.is_positive(); }; }; struct Is_negative: - public CGAL::unary_function{ + public CGAL::cpp98::unary_function{ inline Boolean operator()(const Type &x)const{ return x.is_negative(); }; }; struct Compare: - public CGAL::binary_function{ + public CGAL::cpp98::binary_function{ inline Comparison_result operator() (const Type &x,const Type &y)const{ return x.compare(y); @@ -159,14 +159,14 @@ public INTERN_RET::Real_embeddable_traits_base{ }; struct To_double: - public CGAL::unary_function{ + public CGAL::cpp98::unary_function{ inline double operator()(const Type &x)const{ return x.to_double(); }; }; struct To_interval: - public CGAL::unary_function >{ + public CGAL::cpp98::unary_function >{ inline std::pair operator()(const Type &x)const{ return x.to_interval(); }; @@ -185,86 +185,86 @@ public: typedef CGAL::Tag_false With_empty_interval; typedef CGAL::Tag_true Is_interval; - struct Construct :public CGAL::binary_function{ + struct Construct :public CGAL::cpp98::binary_function{ Interval operator()( const Bound& l,const Bound& r) const { CGAL_precondition( l < r ); return Interval(std::make_pair(l,r)); } }; - struct Lower :public CGAL::unary_function{ + struct Lower :public CGAL::cpp98::unary_function{ Bound operator()( const Interval& a ) const { return a.inf(); } }; - struct Upper :public CGAL::unary_function{ + struct Upper :public CGAL::cpp98::unary_function{ Bound operator()( const Interval& a ) const { return a.sup(); } }; - struct Width :public CGAL::unary_function{ + struct Width :public CGAL::cpp98::unary_function{ Bound operator()( const Interval& a ) const { return Gmpfr::sub(a.sup(),a.inf(),std::round_toward_infinity); } }; - struct Median :public CGAL::unary_function{ + struct Median :public CGAL::cpp98::unary_function{ Bound operator()( const Interval& a ) const { return (a.inf()+a.sup())/2; } }; - struct Norm :public CGAL::unary_function{ + struct Norm :public CGAL::cpp98::unary_function{ Bound operator()( const Interval& a ) const { return a.abs().sup(); } }; - struct Singleton :public CGAL::unary_function{ + struct Singleton :public CGAL::cpp98::unary_function{ bool operator()( const Interval& a ) const { return a.inf() == a.sup(); } }; - struct Zero_in :public CGAL::unary_function{ + struct Zero_in :public CGAL::cpp98::unary_function{ bool operator()( const Interval& a ) const { return a.inf() <= 0 && 0 <= a.sup(); } }; - struct In :public CGAL::binary_function{ + struct In :public CGAL::cpp98::binary_function{ bool operator()( Bound x, const Interval& a ) const { return a.inf() <= x && x <= a.sup(); } }; - struct Equal :public CGAL::binary_function{ + struct Equal :public CGAL::cpp98::binary_function{ bool operator()( const Interval& a, const Interval& b ) const { return a.is_same(b); } }; - struct Overlap :public CGAL::binary_function{ + struct Overlap :public CGAL::cpp98::binary_function{ bool operator()( const Interval& a, const Interval& b ) const { return a.do_overlap(b); } }; - struct Subset :public CGAL::binary_function{ + struct Subset :public CGAL::cpp98::binary_function{ bool operator()( const Interval& a, const Interval& b ) const { return b.inf() <= a.inf() && a.sup() <= b.sup() ; } }; - struct Proper_subset :public CGAL::binary_function{ + struct Proper_subset :public CGAL::cpp98::binary_function{ bool operator()( const Interval& a, const Interval& b ) const { return Subset()(a,b) && ! Equal()(a,b); } }; - struct Hull :public CGAL::binary_function{ + struct Hull :public CGAL::cpp98::binary_function{ Interval operator()( const Interval& a, const Interval& b ) const { BOOST_USING_STD_MAX(); BOOST_USING_STD_MIN(); @@ -278,7 +278,7 @@ public: // struct Empty is Null_functor - struct Intersection :public CGAL::binary_function{ + struct Intersection :public CGAL::cpp98::binary_function{ Interval operator()( const Interval& a, const Interval& b ) const { BOOST_USING_STD_MAX(); BOOST_USING_STD_MIN(); @@ -300,7 +300,7 @@ public: typedef Bigfloat_interval_traits Self; typedef CGAL::Tag_true Is_bigfloat_interval; - struct Relative_precision: public CGAL::unary_function{ + struct Relative_precision: public CGAL::cpp98::unary_function{ long operator()(const NT& x) const { CGAL_precondition(!Singleton()(x)); diff --git a/Number_types/include/CGAL/Gmpfr.h b/Number_types/include/CGAL/Gmpfr.h index c18e7d550ff..61d6e623e5d 100644 --- a/Number_types/include/CGAL/Gmpfr.h +++ b/Number_types/include/CGAL/Gmpfr.h @@ -35,28 +35,28 @@ public: typedef bool Boolean; struct Is_zero: - public CGAL::unary_function{ + public CGAL::cpp98::unary_function{ Boolean operator()(const Type &x)const{ return x.is_zero(); } }; struct Is_one: - public CGAL::unary_function{ + public CGAL::cpp98::unary_function{ Boolean operator()(const Type &x)const{ return x.is_one(); } }; struct Square: - public CGAL::unary_function{ + public CGAL::cpp98::unary_function{ Type operator()(const Type &x)const{ return x.square(); }; }; struct Is_square: - public CGAL::binary_function{ + public CGAL::cpp98::binary_function{ Boolean operator()(const Type &x,Type &y)const{ return x.is_square(y); }; @@ -66,14 +66,14 @@ public: }; struct Sqrt: - public CGAL::unary_function{ + public CGAL::cpp98::unary_function{ Type operator()(const Type &x)const{ return x.sqrt(); }; }; struct Kth_Root: - public CGAL::binary_function{ + public CGAL::cpp98::binary_function{ Type operator()(int k,const Type &x)const{ return (k==3?x.cbrt():x.kthroot(k)); }; @@ -96,42 +96,42 @@ public INTERN_RET::Real_embeddable_traits_base{ typedef AST::Is_zero Is_zero; struct Is_finite: - public CGAL::unary_function{ + public CGAL::cpp98::unary_function{ inline Boolean operator()(const Type &x)const{ return(x.is_number()); }; }; struct Abs: - public CGAL::unary_function{ + public CGAL::cpp98::unary_function{ inline Type operator()(const Type &x)const{ return x.abs(); }; }; struct Sgn: - public CGAL::unary_function{ + public CGAL::cpp98::unary_function{ inline Sign operator()(const Type &x)const{ return x.sign(); }; }; struct Is_positive: - public CGAL::unary_function{ + public CGAL::cpp98::unary_function{ inline Boolean operator()(const Type &x)const{ return(x.sign()==POSITIVE); }; }; struct Is_negative: - public CGAL::unary_function{ + public CGAL::cpp98::unary_function{ inline Boolean operator()(const Type &x)const{ return(x.sign()==NEGATIVE); }; }; struct Compare: - public CGAL::binary_function{ + public CGAL::cpp98::binary_function{ inline Comparison_result operator() (const Type &x,const Type &y)const{ return x.compare(y); @@ -140,14 +140,14 @@ public INTERN_RET::Real_embeddable_traits_base{ }; struct To_double: - public CGAL::unary_function{ + public CGAL::cpp98::unary_function{ inline double operator()(const Type &x)const{ return x.to_double(); }; }; struct To_interval: - public CGAL::unary_function >{ + public CGAL::cpp98::unary_function >{ inline std::pairoperator()(const Type &x)const{ return x.to_interval(); }; diff --git a/Number_types/include/CGAL/Gmpq.h b/Number_types/include/CGAL/Gmpq.h index 8e8a5491da3..37880c94dc2 100644 --- a/Number_types/include/CGAL/Gmpq.h +++ b/Number_types/include/CGAL/Gmpq.h @@ -36,7 +36,7 @@ template <> class Algebraic_structure_traits< Gmpq > typedef Tag_false Is_numerical_sensitive; class Is_square - : public CGAL::binary_function< Type, Type&, + : public CGAL::cpp98::binary_function< Type, Type&, bool > { public: bool operator()( const Type& x_, Type& y ) const { @@ -54,7 +54,7 @@ template <> class Algebraic_structure_traits< Gmpq > }; class Simplify - : public CGAL::unary_function< Type&, void > { + : public CGAL::cpp98::unary_function< Type&, void > { public: void operator()( Type& x) const { mpq_canonicalize( x.mpq() ); @@ -70,7 +70,7 @@ template <> class Real_embeddable_traits< Gmpq > public: class Sgn - : public CGAL::unary_function< Type, ::CGAL::Sign > { + : public CGAL::cpp98::unary_function< Type, ::CGAL::Sign > { public: ::CGAL::Sign operator()( const Type& x ) const { return x.sign(); @@ -78,7 +78,7 @@ template <> class Real_embeddable_traits< Gmpq > }; class To_double - : public CGAL::unary_function< Type, double > { + : public CGAL::cpp98::unary_function< Type, double > { public: double operator()( const Type& x ) const { return x.to_double(); @@ -86,13 +86,18 @@ template <> class Real_embeddable_traits< Gmpq > }; class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { #if MPFR_VERSION_MAJOR >= 3 + mpfr_exp_t emin = mpfr_get_emin(); + mpfr_set_emin(-1073); MPFR_DECL_INIT (y, 53); /* Assume IEEE-754 */ int r = mpfr_set_q (y, x.mpq(), MPFR_RNDA); + r = mpfr_subnormalize (y, r, MPFR_RNDA); /* Round subnormals */ double i = mpfr_get_d (y, MPFR_RNDA); /* EXACT but can overflow */ + mpfr_set_emin(emin); /* Restore old value, users may care */ + // With mpfr_set_emax(1024) we could drop the is_finite test if (r == 0 && is_finite (i)) return std::pair(i, i); else diff --git a/Number_types/include/CGAL/Gmpz.h b/Number_types/include/CGAL/Gmpz.h index 476ea733919..3db122fd159 100644 --- a/Number_types/include/CGAL/Gmpz.h +++ b/Number_types/include/CGAL/Gmpz.h @@ -52,7 +52,7 @@ public: typedef INTERN_AST::Is_square_per_sqrt< Type > Is_square; class Integral_division - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, @@ -65,7 +65,7 @@ public: }; class Gcd - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, @@ -97,7 +97,7 @@ public: typedef INTERN_AST::Mod_per_operator< Type > Mod; class Sqrt - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { Gmpz result; @@ -111,7 +111,7 @@ template <> class Real_embeddable_traits< Gmpz > : public INTERN_RET::Real_embeddable_traits_base< Gmpz , CGAL::Tag_true > { public: class Sgn - : public CGAL::unary_function< Type, ::CGAL::Sign > { + : public CGAL::cpp98::unary_function< Type, ::CGAL::Sign > { public: ::CGAL::Sign operator()( const Type& x ) const { return x.sign(); @@ -119,7 +119,7 @@ public: }; class To_double - : public CGAL::unary_function< Type, double > { + : public CGAL::cpp98::unary_function< Type, double > { public: double operator()( const Type& x ) const { return x.to_double(); @@ -127,7 +127,7 @@ public: }; class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { #if MPFR_VERSION_MAJOR >= 3 @@ -164,7 +164,7 @@ template<> class Algebraic_structure_traits< Quotient > public: typedef Quotient Type; - struct To_double: public CGAL::unary_function, double>{ + struct To_double: public CGAL::cpp98::unary_function, double>{ double operator()(const Quotient& quot){ mpq_t mpQ; mpq_init(mpQ); diff --git a/Number_types/include/CGAL/Gmpzf.h b/Number_types/include/CGAL/Gmpzf.h index 23b2efeb8fa..ef424d6dc57 100644 --- a/Number_types/include/CGAL/Gmpzf.h +++ b/Number_types/include/CGAL/Gmpzf.h @@ -37,7 +37,7 @@ public: typedef Tag_true Is_exact; struct Is_zero - : public CGAL::unary_function< Type, bool > { + : public CGAL::cpp98::unary_function< Type, bool > { public: bool operator()( const Type& x ) const { return x.is_zero(); @@ -45,7 +45,7 @@ public: }; struct Integral_division - : public CGAL::binary_function< Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: @@ -57,7 +57,7 @@ public: }; struct Gcd - : public CGAL::binary_function< Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: @@ -70,7 +70,7 @@ public: }; class Div - : public CGAL::binary_function< Type, Type, Type > { + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, const Type& y ) const { return Type(x).div( y ); @@ -80,7 +80,7 @@ public: typedef INTERN_AST::Mod_per_operator< Type > Mod; class Is_square - : public CGAL::binary_function< Type, Type&, bool > { + : public CGAL::cpp98::binary_function< Type, Type&, bool > { public: bool operator()( const Type& x, Type& y ) const { y = CGAL::approximate_sqrt(x); @@ -104,7 +104,7 @@ public: typedef AST::Is_zero Is_zero; struct Sgn - : public CGAL::unary_function< Type, ::CGAL::Sign > { + : public CGAL::cpp98::unary_function< Type, ::CGAL::Sign > { public: ::CGAL::Sign operator()( const Type& x ) const { return x.sign(); @@ -112,7 +112,7 @@ public: }; struct Compare - : public CGAL::binary_function< Type, + : public CGAL::cpp98::binary_function< Type, Type, Comparison_result > { public: @@ -124,7 +124,7 @@ public: }; struct To_double - : public CGAL::unary_function< Type, double > { + : public CGAL::cpp98::unary_function< Type, double > { public: double operator()( const Type& x ) const { return x.to_double(); @@ -132,7 +132,7 @@ public: }; struct To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { return x.to_interval(); @@ -147,7 +147,7 @@ class Real_embeddable_traits< Quotient > INTERN_QUOTIENT::Real_embeddable_traits_quotient_base< Quotient > { public: - struct To_double: public CGAL::unary_function, double>{ + struct To_double: public CGAL::cpp98::unary_function, double>{ inline double operator()(const Quotient& q) const { std::pair n = q.numerator().to_double_exp(); @@ -158,7 +158,7 @@ public: } }; struct To_interval - : public CGAL::unary_function, std::pair >{ + : public CGAL::cpp98::unary_function, std::pair >{ inline std::pair operator()(const Quotient& q) const { // do here as MP_Float does diff --git a/Number_types/include/CGAL/Interval_nt.h b/Number_types/include/CGAL/Interval_nt.h index 346d14c00a9..131d47da86e 100644 --- a/Number_types/include/CGAL/Interval_nt.h +++ b/Number_types/include/CGAL/Interval_nt.h @@ -446,7 +446,7 @@ relative_precision(const Interval_nt & d) template< bool Protected > class Is_valid< Interval_nt > - : public CGAL::unary_function< Interval_nt, bool > { + : public CGAL::cpp98::unary_function< Interval_nt, bool > { public : bool operator()( const Interval_nt& x ) const { return is_valid(x.inf()) && @@ -683,7 +683,7 @@ operator/ (const Interval_nt & a, double b) // TODO: What about these two guys? Where do they belong to? template struct Min > - : public CGAL::binary_function, + : public CGAL::cpp98::binary_function, Interval_nt, Interval_nt > { @@ -698,7 +698,7 @@ struct Min > template struct Max > - : public CGAL::binary_function, + : public CGAL::cpp98::binary_function, Interval_nt, Interval_nt > { @@ -745,7 +745,7 @@ ldexp(const Interval_nt &i, int e) // TODO: To which concept do these functors belong? Can we remove them?? template < bool b > struct Equal_to < Interval_nt, Interval_nt > - : public CGAL::binary_function< Interval_nt, Interval_nt, Uncertain > + : public CGAL::cpp98::binary_function< Interval_nt, Interval_nt, Uncertain > { Uncertain operator()( const Interval_nt& x, const Interval_nt& y) const @@ -754,7 +754,7 @@ struct Equal_to < Interval_nt, Interval_nt > template < bool b > struct Not_equal_to < Interval_nt, Interval_nt > - : public CGAL::binary_function< Interval_nt, Interval_nt, Uncertain > + : public CGAL::cpp98::binary_function< Interval_nt, Interval_nt, Uncertain > { Uncertain operator()( const Interval_nt& x, const Interval_nt& y) const @@ -763,7 +763,7 @@ struct Not_equal_to < Interval_nt, Interval_nt > template < bool b > struct Greater < Interval_nt, Interval_nt > - : public CGAL::binary_function< Interval_nt, Interval_nt, Uncertain > + : public CGAL::cpp98::binary_function< Interval_nt, Interval_nt, Uncertain > { Uncertain operator()( const Interval_nt& x, const Interval_nt& y) const @@ -772,7 +772,7 @@ struct Greater < Interval_nt, Interval_nt > template < bool b > struct Less < Interval_nt, Interval_nt > - : public CGAL::binary_function< Interval_nt, Interval_nt, Uncertain > + : public CGAL::cpp98::binary_function< Interval_nt, Interval_nt, Uncertain > { Uncertain operator()( const Interval_nt& x, const Interval_nt& y) const @@ -781,7 +781,7 @@ struct Less < Interval_nt, Interval_nt > template < bool b > struct Greater_equal < Interval_nt, Interval_nt > - : public CGAL::binary_function< Interval_nt, Interval_nt, Uncertain > + : public CGAL::cpp98::binary_function< Interval_nt, Interval_nt, Uncertain > { Uncertain operator()( const Interval_nt& x, const Interval_nt& y) const @@ -790,7 +790,7 @@ struct Greater_equal < Interval_nt, Interval_nt > template < bool b > struct Less_equal < Interval_nt, Interval_nt > - : public CGAL::binary_function< Interval_nt, Interval_nt, Uncertain > + : public CGAL::cpp98::binary_function< Interval_nt, Interval_nt, Uncertain > { Uncertain operator()( const Interval_nt& x, const Interval_nt& y) const @@ -943,7 +943,7 @@ template< bool B > class Real_embeddable_traits< Interval_nt > typedef Uncertain Comparison_result; class Abs - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return INTERN_INTERVAL_NT::abs( x ); @@ -951,7 +951,7 @@ template< bool B > class Real_embeddable_traits< Interval_nt > }; class Sgn - : public CGAL::unary_function< Type, Uncertain< ::CGAL::Sign > > { + : public CGAL::cpp98::unary_function< Type, Uncertain< ::CGAL::Sign > > { public: Uncertain< ::CGAL::Sign > operator()( const Type& x ) const { return INTERN_INTERVAL_NT::sign( x ); @@ -959,7 +959,7 @@ template< bool B > class Real_embeddable_traits< Interval_nt > }; class Is_positive - : public CGAL::unary_function< Type, Uncertain > { + : public CGAL::cpp98::unary_function< Type, Uncertain > { public: Uncertain operator()( const Type& x ) const { return INTERN_INTERVAL_NT::is_positive( x ); @@ -967,7 +967,7 @@ template< bool B > class Real_embeddable_traits< Interval_nt > }; class Is_negative - : public CGAL::unary_function< Type, Uncertain > { + : public CGAL::cpp98::unary_function< Type, Uncertain > { public: Uncertain operator()( const Type& x ) const { return INTERN_INTERVAL_NT::is_negative( x ); @@ -975,7 +975,7 @@ template< bool B > class Real_embeddable_traits< Interval_nt > }; class Compare - : public CGAL::binary_function< Type, Type, Comparison_result > { + : public CGAL::cpp98::binary_function< Type, Type, Comparison_result > { public: Comparison_result operator()( const Type& x, const Type& y ) const { return INTERN_INTERVAL_NT::compare( x, y ); @@ -985,7 +985,7 @@ template< bool B > class Real_embeddable_traits< Interval_nt > }; class To_double - : public CGAL::unary_function< Type, double > { + : public CGAL::cpp98::unary_function< Type, double > { public: double operator()( const Type& x ) const { return INTERN_INTERVAL_NT::to_double( x ); @@ -993,7 +993,7 @@ template< bool B > class Real_embeddable_traits< Interval_nt > }; class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { return INTERN_INTERVAL_NT::to_interval( x ); @@ -1001,7 +1001,7 @@ template< bool B > class Real_embeddable_traits< Interval_nt > }; class Is_finite - : public CGAL::unary_function< Type, Boolean > { + : public CGAL::cpp98::unary_function< Type, Boolean > { public : Boolean operator()( const Type& x ) const { return CGAL_NTS is_finite( x.inf() ) && CGAL_NTS is_finite( x.sup() ); @@ -1022,7 +1022,7 @@ class Algebraic_structure_traits< Interval_nt > typedef Uncertain Boolean; class Is_zero - : public CGAL::unary_function< Type, Boolean > { + : public CGAL::cpp98::unary_function< Type, Boolean > { public: Boolean operator()( const Type& x ) const { return INTERN_INTERVAL_NT::is_zero( x ); @@ -1030,7 +1030,7 @@ class Algebraic_structure_traits< Interval_nt > }; class Is_one - : public CGAL::unary_function< Type, Boolean > { + : public CGAL::cpp98::unary_function< Type, Boolean > { public: Boolean operator()( const Type& x ) const { return INTERN_INTERVAL_NT::is_one( x ); @@ -1038,7 +1038,7 @@ class Algebraic_structure_traits< Interval_nt > }; class Square - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return INTERN_INTERVAL_NT::square( x ); @@ -1046,7 +1046,7 @@ class Algebraic_structure_traits< Interval_nt > }; class Sqrt - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return INTERN_INTERVAL_NT::sqrt( x ); @@ -1054,7 +1054,7 @@ class Algebraic_structure_traits< Interval_nt > }; struct Is_square - :public CGAL::binary_function,Interval_nt&,Boolean > + :public CGAL::cpp98::binary_function,Interval_nt&,Boolean > { Boolean operator()(const Interval_nt& x) const { return INTERN_INTERVAL_NT::is_positive( x ); @@ -1077,7 +1077,7 @@ class Algebraic_structure_traits< Interval_nt > }; class Divides - : public CGAL::binary_function< Type, Type, Boolean > { + : public CGAL::cpp98::binary_function< Type, Type, Boolean > { public: Boolean operator()( const Type& x, const Type&) const { return ! Is_zero()(x); @@ -1138,86 +1138,86 @@ public: typedef CGAL::Tag_false With_empty_interval; typedef CGAL::Tag_true Is_interval; - struct Construct :public CGAL::binary_function{ + struct Construct :public CGAL::cpp98::binary_function{ Interval operator()( const Bound& l,const Bound& r) const { CGAL_precondition( l < r ); return Interval(l,r); } }; - struct Lower :public CGAL::unary_function{ + struct Lower :public CGAL::cpp98::unary_function{ Bound operator()( const Interval& a ) const { return a.inf(); } }; - struct Upper :public CGAL::unary_function{ + struct Upper :public CGAL::cpp98::unary_function{ Bound operator()( const Interval& a ) const { return a.sup(); } }; - struct Width :public CGAL::unary_function{ + struct Width :public CGAL::cpp98::unary_function{ Bound operator()( const Interval& a ) const { return width(a); } }; - struct Median :public CGAL::unary_function{ + struct Median :public CGAL::cpp98::unary_function{ Bound operator()( const Interval& a ) const { return (Lower()(a)+Upper()(a))/2.0; } }; - struct Norm :public CGAL::unary_function{ + struct Norm :public CGAL::cpp98::unary_function{ Bound operator()( const Interval& a ) const { return magnitude(a); } }; - struct Singleton :public CGAL::unary_function{ + struct Singleton :public CGAL::cpp98::unary_function{ bool operator()( const Interval& a ) const { return Lower()(a) == Upper()(a); } }; - struct Zero_in :public CGAL::unary_function{ + struct Zero_in :public CGAL::cpp98::unary_function{ bool operator()( const Interval& a ) const { return Lower()(a) <= 0 && 0 <= Upper()(a); } }; - struct In :public CGAL::binary_function{ + struct In :public CGAL::cpp98::binary_function{ bool operator()( Bound x, const Interval& a ) const { return Lower()(a) <= x && x <= Upper()(a); } }; - struct Equal :public CGAL::binary_function{ + struct Equal :public CGAL::cpp98::binary_function{ bool operator()( const Interval& a, const Interval& b ) const { return a.is_same(b); } }; - struct Overlap :public CGAL::binary_function{ + struct Overlap :public CGAL::cpp98::binary_function{ bool operator()( const Interval& a, const Interval& b ) const { return a.do_overlap(b); } }; - struct Subset :public CGAL::binary_function{ + struct Subset :public CGAL::cpp98::binary_function{ bool operator()( const Interval& a, const Interval& b ) const { return Lower()(b) <= Lower()(a) && Upper()(a) <= Upper()(b) ; } }; - struct Proper_subset :public CGAL::binary_function{ + struct Proper_subset :public CGAL::cpp98::binary_function{ bool operator()( const Interval& a, const Interval& b ) const { return Subset()(a,b) && ! Equal()(a,b); } }; - struct Hull :public CGAL::binary_function{ + struct Hull :public CGAL::cpp98::binary_function{ Interval operator()( const Interval& a, const Interval& b ) const { BOOST_USING_STD_MAX(); BOOST_USING_STD_MIN(); @@ -1231,7 +1231,7 @@ public: // struct Empty is Null_functor - struct Intersection :public CGAL::binary_function{ + struct Intersection :public CGAL::cpp98::binary_function{ Interval operator()( const Interval& a, const Interval& b ) const { BOOST_USING_STD_MAX(); BOOST_USING_STD_MIN(); diff --git a/Number_types/include/CGAL/Lazy_exact_nt.h b/Number_types/include/CGAL/Lazy_exact_nt.h index a69313bee8e..aa741a97207 100644 --- a/Number_types/include/CGAL/Lazy_exact_nt.h +++ b/Number_types/include/CGAL/Lazy_exact_nt.h @@ -686,7 +686,7 @@ namespace INTERN_LAZY_EXACT_NT { template< class NT, class Functor > struct Simplify_selector { - struct Simplify : public CGAL::unary_function { + struct Simplify : public CGAL::cpp98::unary_function { void operator()( NT& ) const { // TODO: In the old implementation the Simplify-functor was the default // (which does nothing). But this cannot be the correct way!? @@ -701,7 +701,7 @@ struct Simplify_selector< NT, Null_functor > { template< class NT, class Functor > struct Unit_part_selector { - struct Unit_part : public CGAL::unary_function { + struct Unit_part : public CGAL::cpp98::unary_function { NT operator()( const NT& x ) const { return NT( CGAL_NTS unit_part( x.exact() ) ); } @@ -715,7 +715,7 @@ struct Unit_part_selector< NT, Null_functor > { template< class NT, class Functor > struct Is_zero_selector { - struct Is_zero : public CGAL::unary_function { + struct Is_zero : public CGAL::cpp98::unary_function { bool operator()( const NT& x ) const { return CGAL_NTS is_zero( x.exact() ); } @@ -729,7 +729,7 @@ struct Is_zero_selector< NT, Null_functor > { template< class NT, class Functor > struct Is_one_selector { - struct Is_one : public CGAL::unary_function { + struct Is_one : public CGAL::cpp98::unary_function { bool operator()( const NT& x ) const { return CGAL_NTS is_one( x.exact() ); } @@ -743,7 +743,7 @@ struct Is_one_selector< NT, Null_functor > { template< class NT, class Functor > struct Square_selector { - struct Square : public CGAL::unary_function { + struct Square : public CGAL::cpp98::unary_function { NT operator()( const NT& x ) const { CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); return new Lazy_exact_Square(x); @@ -758,7 +758,7 @@ struct Square_selector< NT, Null_functor > { template< class NT, class Functor > struct Integral_division_selector { - struct Integral_division : public CGAL::binary_function { + struct Integral_division : public CGAL::cpp98::binary_function { NT operator()( const NT& x, const NT& y ) const { return NT( CGAL_NTS integral_division( x.exact(), y.exact() ) ); } @@ -774,7 +774,7 @@ struct Integral_division_selector< NT, Null_functor > { template< class NT, class Functor > struct Is_square_selector { - struct Is_square : public CGAL::binary_function { + struct Is_square : public CGAL::cpp98::binary_function { bool operator()( const NT& x, NT& y ) const { typename NT::ET y_et; bool result = CGAL_NTS is_square( x.exact(), y_et ); @@ -796,7 +796,7 @@ struct Is_square_selector< NT, Null_functor > { template struct Sqrt_selector{ - struct Sqrt : public CGAL::unary_function { + struct Sqrt : public CGAL::cpp98::unary_function { NT operator ()(const NT& x) const { CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); CGAL_precondition(x >= 0); @@ -811,7 +811,7 @@ struct Sqrt_selector { template< class NT, class Functor > struct Kth_root_selector { - struct Kth_root : public CGAL::binary_function { + struct Kth_root : public CGAL::cpp98::binary_function { NT operator()( int k, const NT& x ) const { return NT( CGAL_NTS kth_root( k, x.exact() ) ); } @@ -856,7 +856,7 @@ struct Root_of_selector< NT, Null_functor > { template< class NT, class Functor > struct Gcd_selector { - struct Gcd : public CGAL::binary_function { + struct Gcd : public CGAL::cpp98::binary_function { NT operator()( const NT& x, const NT& y ) const { CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); return NT( CGAL_NTS gcd( x.exact(), y.exact() ) ); @@ -873,7 +873,7 @@ struct Gcd_selector< NT, Null_functor > { template< class NT, class Functor > struct Div_selector { - struct Div : public CGAL::binary_function { + struct Div : public CGAL::cpp98::binary_function { NT operator()( const NT& x, const NT& y ) const { return NT( CGAL_NTS div( x.exact(), y.exact() ) ); } @@ -905,7 +905,7 @@ struct Inverse_selector< NT, Null_functor > { template< class NT, class Functor > struct Mod_selector { - struct Mod : public CGAL::binary_function { + struct Mod : public CGAL::cpp98::binary_function { NT operator()( const NT& x, const NT& y ) const { return NT( CGAL_NTS mod( x.exact(), y.exact() ) ); } @@ -1033,7 +1033,7 @@ template < typename ET > class Real_embeddable_traits< Lazy_exact_nt > typedef Lazy_exact_nt Type; class Abs - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& a ) const { CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); @@ -1042,7 +1042,7 @@ template < typename ET > class Real_embeddable_traits< Lazy_exact_nt > }; class Sgn - : public CGAL::unary_function< Type, ::CGAL::Sign > { + : public CGAL::cpp98::unary_function< Type, ::CGAL::Sign > { public: ::CGAL::Sign operator()( const Type& a ) const { CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); @@ -1055,7 +1055,7 @@ template < typename ET > class Real_embeddable_traits< Lazy_exact_nt > }; class Compare - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Comparison_result > { public: Comparison_result operator()( const Type& a, @@ -1076,7 +1076,7 @@ template < typename ET > class Real_embeddable_traits< Lazy_exact_nt > }; class To_double - : public CGAL::unary_function< Type, double > { + : public CGAL::cpp98::unary_function< Type, double > { public: double operator()( const Type& a ) const { CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); @@ -1101,7 +1101,7 @@ template < typename ET > class Real_embeddable_traits< Lazy_exact_nt > }; class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& a ) const { CGAL_PROFILER(std::string("calls to : ") + std::string(CGAL_PRETTY_FUNCTION)); @@ -1110,7 +1110,7 @@ template < typename ET > class Real_embeddable_traits< Lazy_exact_nt > }; class Is_finite - : public CGAL::unary_function< Type, bool > { + : public CGAL::cpp98::unary_function< Type, bool > { public: bool operator()( const Type& x ) const { return CGAL_NTS is_finite(x.approx()) || CGAL_NTS is_finite(x.exact()); @@ -1216,13 +1216,13 @@ public: typedef Lazy_exact_nt Numerator_type; typedef Lazy_exact_nt Denominator_type; - struct Common_factor : CGAL::binary_function{ + struct Common_factor : CGAL::cpp98::binary_function{ Denominator_type operator()(const Denominator_type& a, const Denominator_type& b) const { typename ETT::Common_factor common_factor; return Denominator_type(common_factor(a.exact(),b.exact())); } }; - struct Compose : CGAL::binary_function{ + struct Compose : CGAL::cpp98::binary_function{ Type operator()(const Numerator_type& n, const Denominator_type& d) const { typename ETT::Compose compose; return Type(compose(n.exact(),d.exact())); @@ -1254,7 +1254,7 @@ class Fraction_traits< Lazy_exact_nt< ET > > template < class ET > struct Min > - : public CGAL::binary_function,Lazy_exact_nt,Lazy_exact_nt > { + : public CGAL::cpp98::binary_function,Lazy_exact_nt,Lazy_exact_nt > { Lazy_exact_nt operator()( const Lazy_exact_nt& x, const Lazy_exact_nt& y) const { @@ -1272,7 +1272,7 @@ struct Min > template < class ET > struct Max > - : public CGAL::binary_function,Lazy_exact_nt,Lazy_exact_nt > { + : public CGAL::cpp98::binary_function,Lazy_exact_nt,Lazy_exact_nt > { Lazy_exact_nt operator()( const Lazy_exact_nt& x, const Lazy_exact_nt& y) const { @@ -1319,7 +1319,7 @@ operator>> (std::istream & is, Lazy_exact_nt & a) template< class ET > class Is_valid< Lazy_exact_nt > - : public CGAL::unary_function< Lazy_exact_nt, bool > { + : public CGAL::cpp98::unary_function< Lazy_exact_nt, bool > { public : bool operator()( const Lazy_exact_nt& x ) const { return is_valid(x.approx()); diff --git a/Number_types/include/CGAL/MP_Float.h b/Number_types/include/CGAL/MP_Float.h index 4b30b36650f..e5ac0299c01 100644 --- a/Number_types/include/CGAL/MP_Float.h +++ b/Number_types/include/CGAL/MP_Float.h @@ -418,7 +418,7 @@ template <> class Algebraic_structure_traits< MP_Float > typedef Tag_true Is_numerical_sensitive; struct Unit_part - : public CGAL::unary_function< Type , Type > + : public CGAL::cpp98::unary_function< Type , Type > { Type operator()(const Type &x) const { return x.unit_part(); @@ -426,7 +426,7 @@ template <> class Algebraic_structure_traits< MP_Float > }; struct Integral_division - : public CGAL::binary_function< Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: @@ -442,7 +442,7 @@ template <> class Algebraic_structure_traits< MP_Float > class Square - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return INTERN_MP_FLOAT::square(x); @@ -450,7 +450,7 @@ template <> class Algebraic_structure_traits< MP_Float > }; class Gcd - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, @@ -460,7 +460,7 @@ template <> class Algebraic_structure_traits< MP_Float > }; class Div - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, @@ -473,7 +473,7 @@ template <> class Algebraic_structure_traits< MP_Float > // Default implementation of Divides functor for unique factorization domains // x divides y if gcd(y,x) equals x up to inverses class Divides - : public CGAL::binary_function{ + : public CGAL::cpp98::binary_function{ public: bool operator()( const Type& x, const Type& y) const { return internal::division(y,x).second == 0 ; @@ -495,7 +495,7 @@ template <> class Real_embeddable_traits< MP_Float > public: class Sgn - : public CGAL::unary_function< Type, ::CGAL::Sign > { + : public CGAL::cpp98::unary_function< Type, ::CGAL::Sign > { public: ::CGAL::Sign operator()( const Type& x ) const { return x.sign(); @@ -503,7 +503,7 @@ template <> class Real_embeddable_traits< MP_Float > }; class Compare - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Comparison_result > { public: Comparison_result operator()( const Type& x, @@ -513,7 +513,7 @@ template <> class Real_embeddable_traits< MP_Float > }; class To_double - : public CGAL::unary_function< Type, double > { + : public CGAL::cpp98::unary_function< Type, double > { public: double operator()( const Type& x ) const { return INTERN_MP_FLOAT::to_double( x ); @@ -521,7 +521,7 @@ template <> class Real_embeddable_traits< MP_Float > }; class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { return INTERN_MP_FLOAT::to_interval( x ); @@ -853,14 +853,14 @@ class Real_embeddable_traits< Quotient > : public INTERN_QUOTIENT::Real_embeddable_traits_quotient_base< Quotient >{ public: - struct To_double: public CGAL::unary_function, double>{ + struct To_double: public CGAL::cpp98::unary_function, double>{ inline double operator()(const Quotient& q) const { return INTERN_MP_FLOAT::to_double(q); } }; struct To_interval - : public CGAL::unary_function, std::pair > { + : public CGAL::cpp98::unary_function, std::pair > { inline std::pair operator()(const Quotient& q) const { return INTERN_MP_FLOAT::to_interval(q); diff --git a/Number_types/include/CGAL/Mpzf.h b/Number_types/include/CGAL/Mpzf.h index e7ee8277bd5..348cb8c81ba 100644 --- a/Number_types/include/CGAL/Mpzf.h +++ b/Number_types/include/CGAL/Mpzf.h @@ -1024,21 +1024,21 @@ std::istream& operator>> (std::istream& is, Mpzf& a) typedef Tag_false Is_numerical_sensitive; struct Is_zero - : public CGAL::unary_function< Type, bool > { + : public CGAL::cpp98::unary_function< Type, bool > { bool operator()( const Type& x ) const { return x.is_zero(); } }; struct Is_one - : public CGAL::unary_function< Type, bool > { + : public CGAL::cpp98::unary_function< Type, bool > { bool operator()( const Type& x ) const { return x.is_one(); } }; struct Gcd - : public CGAL::binary_function< Type, Type, Type > { + : public CGAL::cpp98::binary_function< Type, Type, Type > { Type operator()( const Type& x, const Type& y ) const { @@ -1047,14 +1047,14 @@ std::istream& operator>> (std::istream& is, Mpzf& a) }; struct Square - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { Type operator()( const Type& x ) const { return Mpzf_square(x); } }; struct Integral_division - : public CGAL::binary_function< Type, Type, Type > { + : public CGAL::cpp98::binary_function< Type, Type, Type > { Type operator()( const Type& x, const Type& y ) const { @@ -1063,14 +1063,14 @@ std::istream& operator>> (std::istream& is, Mpzf& a) }; struct Sqrt - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { Type operator()( const Type& x) const { return Mpzf_sqrt(x); } }; struct Is_square - : public CGAL::binary_function< Type, Type&, bool > { + : public CGAL::cpp98::binary_function< Type, Type&, bool > { bool operator()( const Type& x, Type& y ) const { // TODO: avoid doing 2 calls. if (!Mpzf_is_square(x)) return false; @@ -1086,21 +1086,21 @@ std::istream& operator>> (std::istream& is, Mpzf& a) template <> struct Real_embeddable_traits< Mpzf > : public INTERN_RET::Real_embeddable_traits_base< Mpzf , CGAL::Tag_true > { struct Sgn - : public CGAL::unary_function< Type, ::CGAL::Sign > { + : public CGAL::cpp98::unary_function< Type, ::CGAL::Sign > { ::CGAL::Sign operator()( const Type& x ) const { return x.sign(); } }; struct To_double - : public CGAL::unary_function< Type, double > { + : public CGAL::cpp98::unary_function< Type, double > { double operator()( const Type& x ) const { return x.to_double(); } }; struct Compare - : public CGAL::binary_function< Type, Type, Comparison_result > { + : public CGAL::cpp98::binary_function< Type, Type, Comparison_result > { Comparison_result operator()( const Type& x, const Type& y ) const { @@ -1109,7 +1109,7 @@ std::istream& operator>> (std::istream& is, Mpzf& a) }; struct To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { std::pair operator()( const Type& x ) const { return x.to_interval(); } diff --git a/Number_types/include/CGAL/NT_converter.h b/Number_types/include/CGAL/NT_converter.h index fa98a2d6f8a..1e342ca8ec9 100644 --- a/Number_types/include/CGAL/NT_converter.h +++ b/Number_types/include/CGAL/NT_converter.h @@ -34,7 +34,7 @@ namespace CGAL { template < class NT1, class NT2 > struct NT_converter - : public CGAL::unary_function< NT1, NT2 > + : public CGAL::cpp98::unary_function< NT1, NT2 > { NT2 operator()(const NT1 &a) const @@ -50,7 +50,7 @@ struct NT_converter template < class NT1 > struct NT_converter < NT1, NT1 > - : public CGAL::unary_function< NT1, NT1 > + : public CGAL::cpp98::unary_function< NT1, NT1 > { const NT1 & operator()(const NT1 &a) const @@ -61,7 +61,7 @@ struct NT_converter < NT1, NT1 > template < class NT1 > struct NT_converter < NT1, double > - : public CGAL::unary_function< NT1, double > + : public CGAL::cpp98::unary_function< NT1, double > { double operator()(const NT1 &a) const @@ -72,7 +72,7 @@ struct NT_converter < NT1, double > template <> struct NT_converter < double, double > - : public CGAL::unary_function< double, double > + : public CGAL::cpp98::unary_function< double, double > { const double & operator()(const double &a) const @@ -83,7 +83,7 @@ struct NT_converter < double, double > template < class NT1, bool b > struct NT_converter < NT1, Interval_nt > - : public CGAL::unary_function< NT1, Interval_nt > + : public CGAL::cpp98::unary_function< NT1, Interval_nt > { Interval_nt operator()(const NT1 &a) const @@ -94,7 +94,7 @@ struct NT_converter < NT1, Interval_nt > template < bool b > struct NT_converter < Interval_nt, Interval_nt > - : public CGAL::unary_function< Interval_nt, Interval_nt > + : public CGAL::cpp98::unary_function< Interval_nt, Interval_nt > { const Interval_nt & operator()(const Interval_nt &a) const diff --git a/Number_types/include/CGAL/Number_type_checker.h b/Number_types/include/CGAL/Number_type_checker.h index 7c212226acb..e7733dae840 100644 --- a/Number_types/include/CGAL/Number_type_checker.h +++ b/Number_types/include/CGAL/Number_type_checker.h @@ -402,7 +402,7 @@ operator>=(int i, const Number_type_checker &b) template < typename NT1, typename NT2, typename Cmp > class Is_valid< Number_type_checker > - : public CGAL::unary_function< Number_type_checker , bool > { + : public CGAL::cpp98::unary_function< Number_type_checker , bool > { public : bool operator()(const Number_type_checker& a ) const { bool b1 = is_valid(a.n1()); @@ -435,7 +435,7 @@ private: public: //CGAL::Algebraic_structure_traits<>::Simplify class Simplify - : public CGAL::unary_function< Type& , void > { + : public CGAL::cpp98::unary_function< Type& , void > { public: void operator()( Type& a) const { typename AST1::Simplify()(a.n1()); @@ -446,7 +446,7 @@ public: //CGAL::Algebraic_structure_traits< >::Is_zero class Is_zero - : public CGAL::unary_function< Type, bool > { + : public CGAL::cpp98::unary_function< Type, bool > { public: bool operator()(const Type& a ) const { bool b1 = typename AST1::Is_zero()(a.n1()); @@ -458,7 +458,7 @@ public: // CGAL::Algebraic_structure_traits< >::Is_one class Is_one - : public CGAL::unary_function< Type, bool > { + : public CGAL::cpp98::unary_function< Type, bool > { public: bool operator()(const Type& a) const { bool b1 = typename AST1::Is_one()(a.n1()); @@ -469,7 +469,7 @@ public: }; // CGAL::Algebraic_structure_traits< >::Square class Square - : public CGAL::unary_function< Type , Type > { + : public CGAL::cpp98::unary_function< Type , Type > { public: Type operator()(const Type& a) const { return Type( @@ -481,7 +481,7 @@ public: // CGAL::Algebraic_structure_traits< >::Unit_part class Unit_part - : public CGAL::unary_function< Type , Type > { + : public CGAL::cpp98::unary_function< Type , Type > { public: Type operator()(const Type& a) const { CGAL_NT_CHECK_DEBUG("AST::Unit_part"); @@ -507,7 +507,7 @@ public: // CGAL::Algebraic_structure_traits< >::Integral_division class Integral_division - : public CGAL::binary_function< Type, Type, Type > { + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& a, const Type& b) const { CGAL_NT_CHECK_DEBUG("AST::Integral_division"); @@ -518,7 +518,7 @@ public: }; class Divides - : public CGAL::binary_function< Type, Type, bool > { + : public CGAL::cpp98::binary_function< Type, Type, bool > { public: bool operator()( const Type& a, const Type& b) const { CGAL_NT_CHECK_DEBUG("AST::Divides"); @@ -555,7 +555,7 @@ private: public: // CGAL::Algebraic_structure_traits< >::Gcd class Gcd - : public CGAL::binary_function< Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: @@ -583,7 +583,7 @@ private: public: // CGAL::Algebraic_structure_traits< >::Div class Div - : public CGAL::binary_function< Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: @@ -598,7 +598,7 @@ public: }; // CGAL::Algebraic_structure_traits< >::Mod class Mod - : public CGAL::binary_function< Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: @@ -650,7 +650,7 @@ private: typedef Number_type_checker Type; public: class Inverse - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& a ) const { NT1 r1 = typename AST1::Inverse()(a.n1()); @@ -677,7 +677,7 @@ public: // CGAL::Algebraic_structure_traits< >::Sqrt class Sqrt - : public CGAL::unary_function< Type , Type > { + : public CGAL::cpp98::unary_function< Type , Type > { public: Type operator()(const Type& a) const { CGAL_NT_CHECK_DEBUG("AST::Sqrt"); @@ -726,7 +726,7 @@ public: // CGAL::Real_embeddable_traits< >::Abs class Abs - : public CGAL::unary_function< Type , Type > { + : public CGAL::cpp98::unary_function< Type , Type > { public: Type operator()(const Type& a) const { CGAL_NT_CHECK_DEBUG("RET::Abs"); @@ -738,7 +738,7 @@ public: // CGAL::Real_embeddable_traits< >::Sign class Sgn - : public CGAL::unary_function< Type , ::CGAL::Sign > { + : public CGAL::cpp98::unary_function< Type , ::CGAL::Sign > { public: ::CGAL::Sign operator()(const Type& a) const { CGAL_NT_CHECK_DEBUG("RET::Sign"); @@ -750,7 +750,7 @@ public: // CGAL::Real_embeddable_traits< >::Is_finite class Is_finite - : public CGAL::unary_function< Type , bool > { + : public CGAL::cpp98::unary_function< Type , bool > { public: bool operator()(const Type& a) const { CGAL_NT_CHECK_DEBUG("RET::Is_finite"); @@ -762,7 +762,7 @@ public: // CGAL::Real_embeddable_traits< >::Is_positive class Is_positive - : public CGAL::unary_function< Type , bool > { + : public CGAL::cpp98::unary_function< Type , bool > { public: bool operator()(const Type& a) const { CGAL_NT_CHECK_DEBUG("RET::Is_positive"); @@ -774,7 +774,7 @@ public: // CGAL::Real_embeddable_traits< >::Is_negative class Is_negative - : public CGAL::unary_function< Type , bool > { + : public CGAL::cpp98::unary_function< Type , bool > { public: bool operator()(const Type& a) const { CGAL_NT_CHECK_DEBUG("RET::Is_negative"); @@ -786,7 +786,7 @@ public: // CGAL::Real_embeddable_traits< >::Is_zero class Is_zero - : public CGAL::unary_function< Type , bool > { + : public CGAL::cpp98::unary_function< Type , bool > { public: bool operator()(const Type& a) const { CGAL_NT_CHECK_DEBUG("RET::Is_zero"); @@ -798,7 +798,7 @@ public: // CGAL::Real_embeddable_traits< >::Compare class Compare - : public CGAL::binary_function< Type , Type, Comparison_result > { + : public CGAL::cpp98::binary_function< Type , Type, Comparison_result > { public: Comparison_result operator()(const Type& a, const Type& b) const { CGAL_NT_CHECK_DEBUG("RET::Compare"); @@ -810,7 +810,7 @@ public: // CGAL::Real_embeddable_traits< >::To_double class To_double - : public CGAL::unary_function< Type , double > { + : public CGAL::cpp98::unary_function< Type , double > { public: double operator()(const Type& a) const { CGAL_NT_CHECK_DEBUG("RET::To_double"); @@ -822,7 +822,7 @@ public: // CGAL::Real_embeddable_traits< >::To_interval class To_interval - : public CGAL::unary_function< Type , std::pair > { + : public CGAL::cpp98::unary_function< Type , std::pair > { public: std::pair operator()(const Type& a) const { CGAL_NT_CHECK_DEBUG("RET::To_interval"); diff --git a/Number_types/include/CGAL/Quotient.h b/Number_types/include/CGAL/Quotient.h index 46a2e3a3c6e..800620d7c0e 100644 --- a/Number_types/include/CGAL/Quotient.h +++ b/Number_types/include/CGAL/Quotient.h @@ -548,7 +548,7 @@ operator>(const Quotient& x, const CGAL_double(NT)& y) template< class NT > class Is_valid< Quotient > - : public CGAL::unary_function< Quotient, bool > { + : public CGAL::cpp98::unary_function< Quotient, bool > { public : bool operator()( const Quotient& x ) const { return is_valid(x.num) && is_valid(x.den); @@ -607,7 +607,7 @@ namespace INTERN_QUOTIENT { class Sqrt_selector { public: class Sqrt - : public CGAL::unary_function< NT, NT > { + : public CGAL::cpp98::unary_function< NT, NT > { public: NT operator()( const NT& x ) const { CGAL_precondition(x > 0); @@ -639,7 +639,7 @@ public: class Is_square - : public CGAL::binary_function< Quotient, Quotient&, bool > { + : public CGAL::cpp98::binary_function< Quotient, Quotient&, bool > { public: bool operator()( Quotient x, Quotient& y ) const { NT x_num, x_den, y_num, y_den; @@ -670,7 +670,7 @@ public: >::type Sqrt; class Simplify - : public CGAL::unary_function< Type&, void > { + : public CGAL::cpp98::unary_function< Type&, void > { public: void operator()( Type& x) const { x.normalize(); @@ -688,7 +688,7 @@ template < class NT > class Real_embeddable_traits_quotient_base< Quotient > typedef Quotient Type; class Compare - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Comparison_result > { public: Comparison_result operator()( const Type& x, @@ -698,7 +698,7 @@ template < class NT > class Real_embeddable_traits_quotient_base< Quotient > }; class To_double - : public CGAL::unary_function< Type, double > { + : public CGAL::cpp98::unary_function< Type, double > { public: double operator()( const Type& x ) const { // Original global function was marked with an TODO!! @@ -730,7 +730,7 @@ template < class NT > class Real_embeddable_traits_quotient_base< Quotient > }; class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { Interval_nt<> quot = @@ -741,7 +741,7 @@ template < class NT > class Real_embeddable_traits_quotient_base< Quotient > }; class Is_finite - : public CGAL::unary_function< Type, bool > { + : public CGAL::cpp98::unary_function< Type, bool > { public: bool operator()( const Type& x ) const { return CGAL_NTS is_finite(x.num) && CGAL_NTS is_finite(x.den); diff --git a/Number_types/include/CGAL/Sqrt_extension/Algebraic_structure_traits.h b/Number_types/include/CGAL/Sqrt_extension/Algebraic_structure_traits.h index 4528bcdf8c9..cf8fddfe189 100644 --- a/Number_types/include/CGAL/Sqrt_extension/Algebraic_structure_traits.h +++ b/Number_types/include/CGAL/Sqrt_extension/Algebraic_structure_traits.h @@ -42,7 +42,7 @@ class Sqrt_extension_algebraic_structure_traits_base< Type, typedef CGAL::Integral_domain_without_division_tag Algebraic_category; class Simplify - : public CGAL::unary_function< Type&, void > { + : public CGAL::cpp98::unary_function< Type&, void > { public: typedef void result_type; typedef Type& argument_type; @@ -62,7 +62,7 @@ public: typedef CGAL::Integral_domain_tag Algebraic_category; class Integral_division - : public CGAL::binary_function< Type, Type, Type > { + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x,const Type& y ) const { return x/y; @@ -78,7 +78,7 @@ private: typedef typename AST_COEFF::Divides Divides_coeff; public: class Divides - : public CGAL::binary_function{ + : public CGAL::cpp98::binary_function{ typedef typename Divides_coeff::result_type BOOL; public: BOOL operator()( const Type& x, const Type& y) const { @@ -160,14 +160,14 @@ class Sqrt_extension_algebraic_structure_traits_base< Type, typedef Field_tag Algebraic_category; class Unit_part - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return( x == Type(0) ? Type(1) : x ); } }; class Inverse - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return Type(1)/x ; diff --git a/Number_types/include/CGAL/Sqrt_extension/Real_embeddable_traits.h b/Number_types/include/CGAL/Sqrt_extension/Real_embeddable_traits.h index b3d9c96b33a..06198082f19 100644 --- a/Number_types/include/CGAL/Sqrt_extension/Real_embeddable_traits.h +++ b/Number_types/include/CGAL/Sqrt_extension/Real_embeddable_traits.h @@ -36,7 +36,7 @@ class Real_embeddable_traits< Sqrt_extension > typedef Sqrt_extension Type; class Sgn - : public CGAL::unary_function< Type, ::CGAL::Sign >{ + : public CGAL::cpp98::unary_function< Type, ::CGAL::Sign >{ public: ::CGAL::Sign operator()( const Type& x ) const { return x.sign(); @@ -44,7 +44,7 @@ class Real_embeddable_traits< Sqrt_extension > }; class Compare - : public CGAL::binary_function< Type, Type, Comparison_result > { + : public CGAL::cpp98::binary_function< Type, Type, Comparison_result > { public: Comparison_result operator()( const Type& x, const Type& y) const { // must be from the same extension @@ -64,7 +64,7 @@ class Real_embeddable_traits< Sqrt_extension > }; class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()(const Type& x) const { return x.to_interval(); @@ -72,7 +72,7 @@ class Real_embeddable_traits< Sqrt_extension > }; class To_double - : public CGAL::unary_function< Type, double > { + : public CGAL::cpp98::unary_function< Type, double > { public: // The main problem here is, that even tough the total // expression fits into double, one of the coefficients diff --git a/Number_types/include/CGAL/Sqrt_extension/Sqrt_extension_type.h b/Number_types/include/CGAL/Sqrt_extension/Sqrt_extension_type.h index 56a13bdea86..da6b2c16058 100644 --- a/Number_types/include/CGAL/Sqrt_extension/Sqrt_extension_type.h +++ b/Number_types/include/CGAL/Sqrt_extension/Sqrt_extension_type.h @@ -680,7 +680,7 @@ Sqrt_extension square (const Sqrt_extension struct NT_converter < Sqrt_extension , Sqrt_extension > - : public CGAL::unary_function< NT1, NT2 > + : public CGAL::cpp98::unary_function< NT1, NT2 > { Sqrt_extension operator()(const Sqrt_extension &a) const @@ -698,7 +698,7 @@ struct NT_converter < Sqrt_extension , Sqrt_extension template struct NT_converter < NT1 , Sqrt_extension > - : public CGAL::unary_function< NT1, NT2 > + : public CGAL::cpp98::unary_function< NT1, NT2 > { Sqrt_extension operator()(const NT1 &a) const @@ -710,7 +710,7 @@ struct NT_converter < NT1 , Sqrt_extension > //needed because it's a better match than the specialization template struct NT_converter < Sqrt_extension, Sqrt_extension > - : public CGAL::unary_function< NT1, NT1 > + : public CGAL::cpp98::unary_function< NT1, NT1 > { const Sqrt_extension& operator()(const Sqrt_extension &a) const diff --git a/Number_types/include/CGAL/Sqrt_extension/convert_to_bfi.h b/Number_types/include/CGAL/Sqrt_extension/convert_to_bfi.h index 7ff25d562b1..2af7a86db94 100644 --- a/Number_types/include/CGAL/Sqrt_extension/convert_to_bfi.h +++ b/Number_types/include/CGAL/Sqrt_extension/convert_to_bfi.h @@ -49,7 +49,7 @@ class Sqrt_extension_bfi_cache { typedef typename Coercion_traits::Cast Cast; typedef typename Algebraic_structure_traits::Sqrt Sqrt; - struct Creator : public CGAL::unary_function { + struct Creator : public CGAL::cpp98::unary_function { BFI operator()(const Input& pair){ return Sqrt()(Cast()(pair.second)); } diff --git a/Number_types/include/CGAL/double.h b/Number_types/include/CGAL/double.h index c96d7319c5b..0d924c7cb75 100644 --- a/Number_types/include/CGAL/double.h +++ b/Number_types/include/CGAL/double.h @@ -73,7 +73,7 @@ is_nan_by_mask_double(unsigned int h, unsigned int l) template<> class Is_valid< double > - : public CGAL::unary_function< double, bool > { + : public CGAL::cpp98::unary_function< double, bool > { public : bool operator()( const double& x ) const{ double d = x; @@ -86,7 +86,7 @@ class Is_valid< double > template<> class Is_valid< double > - : public CGAL::unary_function< double, bool > { + : public CGAL::cpp98::unary_function< double, bool > { public : bool operator()( const double& x ) const { #ifdef _MSC_VER @@ -107,7 +107,7 @@ template <> class Algebraic_structure_traits< double > typedef Tag_true Is_numerical_sensitive; class Sqrt - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return std::sqrt( x ); @@ -115,7 +115,7 @@ template <> class Algebraic_structure_traits< double > }; class Kth_root - : public CGAL::binary_function { + : public CGAL::cpp98::binary_function { public: Type operator()( int k, const Type& x) const { @@ -152,7 +152,7 @@ template <> class Real_embeddable_traits< double > // GCC is faster with std::fabs(). #if defined(__GNUG__) || defined(CGAL_MSVC_USE_STD_FABS) || defined(CGAL_USE_SSE2_FABS) class Abs - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { #ifdef CGAL_USE_SSE2_FABS @@ -166,7 +166,7 @@ template <> class Real_embeddable_traits< double > // Is_finite depends on platform class Is_finite - : public CGAL::unary_function< Type, bool > { + : public CGAL::cpp98::unary_function< Type, bool > { public : bool operator()( const Type& x ) const { diff --git a/Number_types/include/CGAL/float.h b/Number_types/include/CGAL/float.h index 240d27acf02..5377b6e87f1 100644 --- a/Number_types/include/CGAL/float.h +++ b/Number_types/include/CGAL/float.h @@ -63,7 +63,7 @@ is_nan_by_mask_float(unsigned int u) template<> class Is_valid< float > - : public CGAL::unary_function< float, bool > { + : public CGAL::cpp98::unary_function< float, bool > { public : bool operator()( const float& x ) const { float f = x; @@ -76,7 +76,7 @@ class Is_valid< float > template<> class Is_valid< float > - : public CGAL::unary_function< float, bool > { + : public CGAL::cpp98::unary_function< float, bool > { public : bool operator()( const float& x ) const { return (x == x); @@ -93,7 +93,7 @@ template <> class Algebraic_structure_traits< float > typedef Tag_true Is_numerical_sensitive; class Sqrt - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return std::sqrt( x ); @@ -101,7 +101,7 @@ template <> class Algebraic_structure_traits< float > }; class Kth_root - : public CGAL::binary_function { + : public CGAL::cpp98::binary_function { public: Type operator()( int k, const Type& x) const { CGAL_precondition_msg( k > 0, "'k' must be positive for k-th roots"); @@ -116,7 +116,7 @@ template <> class Real_embeddable_traits< float > public: // Is_finite depends on platform class Is_finite - : public CGAL::unary_function< Type, bool > { + : public CGAL::cpp98::unary_function< Type, bool > { public: bool operator()( const Type& x ) const { diff --git a/Number_types/include/CGAL/int.h b/Number_types/include/CGAL/int.h index 07a9bef19c7..9b9e905926c 100644 --- a/Number_types/include/CGAL/int.h +++ b/Number_types/include/CGAL/int.h @@ -38,7 +38,7 @@ namespace CGAL { namespace INTERN_INT { template< class Type > class Is_square_per_double_conversion - : public CGAL::binary_function< Type, Type&, + : public CGAL::cpp98::binary_function< Type, Type&, bool > { public: bool operator()( const Type& x, @@ -122,7 +122,7 @@ template <> class Real_embeddable_traits< long int > public: class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { return Interval_nt(x).pair(); @@ -169,7 +169,7 @@ template<> class Algebraic_structure_traits< short int > // interoperability. This is nescessary because of the implicit conversion // to int for binary operations between short ints. class Integral_division - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, @@ -183,7 +183,7 @@ template<> class Algebraic_structure_traits< short int > }; class Gcd - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, @@ -243,7 +243,7 @@ template<> class Algebraic_structure_traits< short int > // based on \c Div_mod. class Div - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, @@ -254,7 +254,7 @@ template<> class Algebraic_structure_traits< short int > // based on \c Div_mod. class Mod - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, @@ -282,7 +282,7 @@ template <> class Real_embeddable_traits< unsigned long > public: class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { return Interval_nt(x).pair(); diff --git a/Number_types/include/CGAL/leda_bigfloat.h b/Number_types/include/CGAL/leda_bigfloat.h index 72f5759212c..1c000d64143 100644 --- a/Number_types/include/CGAL/leda_bigfloat.h +++ b/Number_types/include/CGAL/leda_bigfloat.h @@ -45,7 +45,7 @@ template <> class Algebraic_structure_traits< leda_bigfloat > typedef Tag_true Is_numerical_sensitive; class Sqrt - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return CGAL_LEDA_SCOPE::sqrt( x ); @@ -53,7 +53,7 @@ template <> class Algebraic_structure_traits< leda_bigfloat > }; class Kth_root - : public CGAL::binary_function { + : public CGAL::cpp98::binary_function { public: Type operator()( int k, const Type& x) const { @@ -73,7 +73,7 @@ template <> class Real_embeddable_traits< leda_bigfloat > public: class Abs - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return CGAL_LEDA_SCOPE::abs( x ); @@ -81,7 +81,7 @@ public: }; class Sgn - : public CGAL::unary_function< Type, ::CGAL::Sign > { + : public CGAL::cpp98::unary_function< Type, ::CGAL::Sign > { public: ::CGAL::Sign operator()( const Type& x ) const { return (::CGAL::Sign) CGAL_LEDA_SCOPE::sign( x ); @@ -89,7 +89,7 @@ public: }; class Compare - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Comparison_result > { public: Comparison_result operator()( const Type& x, @@ -102,7 +102,7 @@ public: }; class To_double - : public CGAL::unary_function< Type, double > { + : public CGAL::cpp98::unary_function< Type, double > { public: double operator()( const Type& x ) const { return x.to_double(); @@ -110,7 +110,7 @@ public: }; class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { @@ -124,7 +124,7 @@ public: }; class Is_finite - : public CGAL::unary_function< Type, bool > { + : public CGAL::cpp98::unary_function< Type, bool > { public: bool operator()( const Type& x ) const { return !( CGAL_LEDA_SCOPE::isInf(x) || CGAL_LEDA_SCOPE::isNaN(x) ); @@ -134,7 +134,7 @@ public: template<> class Is_valid< leda_bigfloat > - : public CGAL::unary_function< leda_bigfloat, bool > { + : public CGAL::cpp98::unary_function< leda_bigfloat, bool > { public : bool operator()( const leda_bigfloat& x ) const { return !( CGAL_LEDA_SCOPE::isNaN(x) ); diff --git a/Number_types/include/CGAL/leda_bigfloat_interval.h b/Number_types/include/CGAL/leda_bigfloat_interval.h index d2e6b268852..b07cfc5062b 100644 --- a/Number_types/include/CGAL/leda_bigfloat_interval.h +++ b/Number_types/include/CGAL/leda_bigfloat_interval.h @@ -176,7 +176,7 @@ public: typedef Tag_true Is_numerical_sensitive; class Sqrt - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return ::boost::numeric::sqrt(x); @@ -189,7 +189,7 @@ template <> class Real_embeddable_traits< leda_bigfloat_interval > public: class Abs - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return ::boost::numeric::abs(x); @@ -197,7 +197,7 @@ public: }; class To_double - : public CGAL::unary_function< Type, double > { + : public CGAL::cpp98::unary_function< Type, double > { public: double operator()( const Type& x ) const { return CGAL::to_double(::boost::numeric::median(x)); @@ -205,7 +205,7 @@ public: }; class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { std::pair lower_I(CGAL::to_interval(x.lower())); @@ -314,98 +314,98 @@ public: typedef CGAL::Tag_true Is_interval; typedef CGAL::Tag_true With_empty_interval; - struct Construct :public CGAL::binary_function{ + struct Construct :public CGAL::cpp98::binary_function{ Interval operator()( const Bound& l,const Bound& r) const { CGAL_precondition( l < r ); return Interval(l,r); } }; - struct Lower :public CGAL::unary_function{ + struct Lower :public CGAL::cpp98::unary_function{ Bound operator()( const Interval& a ) const { return a.lower(); } }; - struct Upper :public CGAL::unary_function{ + struct Upper :public CGAL::cpp98::unary_function{ Bound operator()( const Interval& a ) const { return a.upper(); } }; - struct Width :public CGAL::unary_function{ + struct Width :public CGAL::cpp98::unary_function{ Bound operator()( const Interval& a ) const { return ::boost::numeric::width(a); } }; - struct Median :public CGAL::unary_function{ + struct Median :public CGAL::cpp98::unary_function{ Bound operator()( const Interval& a ) const { return ::boost::numeric::median(a); } }; - struct Norm :public CGAL::unary_function{ + struct Norm :public CGAL::cpp98::unary_function{ Bound operator()( const Interval& a ) const { return ::boost::numeric::norm(a); } }; - struct Empty :public CGAL::unary_function{ + struct Empty :public CGAL::cpp98::unary_function{ bool operator()( const Interval& a ) const { return ::boost::numeric::empty(a); } }; - struct Singleton :public CGAL::unary_function{ + struct Singleton :public CGAL::cpp98::unary_function{ bool operator()( const Interval& a ) const { return ::boost::numeric::singleton(a); } }; - struct Zero_in :public CGAL::unary_function{ + struct Zero_in :public CGAL::cpp98::unary_function{ bool operator()( const Interval& a ) const { return ::boost::numeric::in_zero(a); } }; - struct In :public CGAL::binary_function{ + struct In :public CGAL::cpp98::binary_function{ bool operator()( Bound x, const Interval& a ) const { return ::boost::numeric::in(x,a); } }; - struct Equal :public CGAL::binary_function{ + struct Equal :public CGAL::cpp98::binary_function{ bool operator()( const Interval& a, const Interval& b ) const { return ::boost::numeric::equal(a,b); } }; - struct Overlap :public CGAL::binary_function{ + struct Overlap :public CGAL::cpp98::binary_function{ bool operator()( const Interval& a, const Interval& b ) const { return ::boost::numeric::overlap(a,b); } }; - struct Subset :public CGAL::binary_function{ + struct Subset :public CGAL::cpp98::binary_function{ bool operator()( const Interval& a, const Interval& b ) const { return ::boost::numeric::subset(a,b); } }; - struct Proper_subset :public CGAL::binary_function{ + struct Proper_subset :public CGAL::cpp98::binary_function{ bool operator()( const Interval& a, const Interval& b ) const { return ::boost::numeric::proper_subset(a,b); } }; - struct Hull :public CGAL::binary_function{ + struct Hull :public CGAL::cpp98::binary_function{ Interval operator()( const Interval& a, const Interval& b ) const { return ::boost::numeric::hull(a,b); } }; - struct Intersection :public CGAL::binary_function{ + struct Intersection :public CGAL::cpp98::binary_function{ Interval operator()( const Interval& a, const Interval& b ) const { Interval r = ::boost::numeric::intersect(a,b); return r; @@ -424,7 +424,7 @@ public: typedef CGAL::Tag_true Is_bigfloat_interval; -// struct Get_significant_bits : public CGAL::unary_function{ +// struct Get_significant_bits : public CGAL::cpp98::unary_function{ // long operator()( NT x) const { // CGAL_precondition(!Singleton()(x)); // leda::bigfloat lower = x.lower(); @@ -444,7 +444,7 @@ public: // }; - struct Relative_precision: public CGAL::unary_function{ + struct Relative_precision: public CGAL::cpp98::unary_function{ long operator()(const NT& x) const { CGAL_precondition(!Singleton()(x)); CGAL_precondition(!CGAL::zero_in(x)); @@ -455,7 +455,7 @@ public: } }; - struct Set_precision : public CGAL::unary_function { + struct Set_precision : public CGAL::cpp98::unary_function { long operator()( long prec ) const { return BF::set_precision(prec); } diff --git a/Number_types/include/CGAL/leda_integer.h b/Number_types/include/CGAL/leda_integer.h index 79d903c8349..fac165b4c07 100644 --- a/Number_types/include/CGAL/leda_integer.h +++ b/Number_types/include/CGAL/leda_integer.h @@ -54,7 +54,7 @@ template <> class Algebraic_structure_traits< leda_integer > Is_square; class Gcd - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Type > { public: Type operator()( const Type& x, @@ -107,7 +107,7 @@ template <> class Algebraic_structure_traits< leda_integer > // typedef INTERN_AST::Div_per_operator< Type > Div; // class Mod -// : public CGAL::binary_function< Type, Type, +// : public CGAL::cpp98::binary_function< Type, Type, // Type > { // public: // Type operator()( const Type& x, const Type& y ) const { @@ -118,7 +118,7 @@ template <> class Algebraic_structure_traits< leda_integer > // }; class Sqrt - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return CGAL_LEDA_SCOPE::sqrt( x ); @@ -131,7 +131,7 @@ template <> class Real_embeddable_traits< leda_integer > public: class Abs - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return CGAL_LEDA_SCOPE::abs( x ); @@ -139,7 +139,7 @@ template <> class Real_embeddable_traits< leda_integer > }; class Sgn - : public CGAL::unary_function< Type, ::CGAL::Sign > { + : public CGAL::cpp98::unary_function< Type, ::CGAL::Sign > { public: ::CGAL::Sign operator()( const Type& x ) const { return (::CGAL::Sign) CGAL_LEDA_SCOPE::sign( x ); @@ -147,7 +147,7 @@ template <> class Real_embeddable_traits< leda_integer > }; class Compare - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Comparison_result > { public: Comparison_result operator()( const Type& x, @@ -158,7 +158,7 @@ template <> class Real_embeddable_traits< leda_integer > }; class To_double - : public CGAL::unary_function< Type, double > { + : public CGAL::cpp98::unary_function< Type, double > { public: double operator()( const Type& x ) const { return x.to_double(); @@ -166,7 +166,7 @@ template <> class Real_embeddable_traits< leda_integer > }; class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { leda::bigfloat h(x); diff --git a/Number_types/include/CGAL/leda_rational.h b/Number_types/include/CGAL/leda_rational.h index b2f3ee9d90a..9a1ce3fceae 100644 --- a/Number_types/include/CGAL/leda_rational.h +++ b/Number_types/include/CGAL/leda_rational.h @@ -64,7 +64,7 @@ template <> class Algebraic_structure_traits< leda_rational > // Is_square; class Simplify - : public CGAL::unary_function< Type&, void > { + : public CGAL::cpp98::unary_function< Type&, void > { public: void operator()( Type& x) const { x.normalize(); @@ -78,7 +78,7 @@ template <> class Real_embeddable_traits< leda_rational > public: class Abs - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return CGAL_LEDA_SCOPE::abs( x ); @@ -86,7 +86,7 @@ template <> class Real_embeddable_traits< leda_rational > }; class Sgn - : public CGAL::unary_function< Type, ::CGAL::Sign > { + : public CGAL::cpp98::unary_function< Type, ::CGAL::Sign > { public: ::CGAL::Sign operator()( const Type& x ) const { return (::CGAL::Sign) CGAL_LEDA_SCOPE::sign( x ); @@ -94,7 +94,7 @@ template <> class Real_embeddable_traits< leda_rational > }; class Compare - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Comparison_result > { public: Comparison_result operator()( const Type& x, @@ -105,7 +105,7 @@ template <> class Real_embeddable_traits< leda_rational > }; class To_double - : public CGAL::unary_function< Type, double > { + : public CGAL::cpp98::unary_function< Type, double > { public: double operator()( const Type& x ) const { return x.to_double(); @@ -113,7 +113,7 @@ template <> class Real_embeddable_traits< leda_rational > }; class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { diff --git a/Number_types/include/CGAL/leda_real.h b/Number_types/include/CGAL/leda_real.h index 6090fdb22e1..51fe924ea61 100644 --- a/Number_types/include/CGAL/leda_real.h +++ b/Number_types/include/CGAL/leda_real.h @@ -51,7 +51,7 @@ template <> class Algebraic_structure_traits< leda_real > typedef Tag_true Is_numerical_sensitive; class Sqrt - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return CGAL_LEDA_SCOPE::sqrt( x ); @@ -59,7 +59,7 @@ template <> class Algebraic_structure_traits< leda_real > }; class Kth_root - : public CGAL::binary_function { + : public CGAL::cpp98::binary_function { public: Type operator()( int k, const Type& x) const { @@ -110,7 +110,7 @@ template <> class Real_embeddable_traits< leda_real > : public INTERN_RET::Real_embeddable_traits_base< leda_real , CGAL::Tag_true > { public: class Abs - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return CGAL_LEDA_SCOPE::abs( x ); @@ -118,7 +118,7 @@ template <> class Real_embeddable_traits< leda_real > }; class Sgn - : public CGAL::unary_function< Type, ::CGAL::Sign > { + : public CGAL::cpp98::unary_function< Type, ::CGAL::Sign > { public: ::CGAL::Sign operator()( const Type& x ) const { return (::CGAL::Sign) CGAL_LEDA_SCOPE::sign( x ); @@ -126,7 +126,7 @@ template <> class Real_embeddable_traits< leda_real > }; class Compare - : public CGAL::binary_function< Type, Type, + : public CGAL::cpp98::binary_function< Type, Type, Comparison_result > { public: Comparison_result operator()( const Type& x, @@ -140,7 +140,7 @@ template <> class Real_embeddable_traits< leda_real > }; class To_double - : public CGAL::unary_function< Type, double > { + : public CGAL::cpp98::unary_function< Type, double > { public: double operator()( const Type& x ) const { // this call is required to get reasonable values for the double @@ -151,7 +151,7 @@ template <> class Real_embeddable_traits< leda_real > }; class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { diff --git a/Number_types/include/CGAL/long_double.h b/Number_types/include/CGAL/long_double.h index 14a501d1c5e..0a19a1fb270 100644 --- a/Number_types/include/CGAL/long_double.h +++ b/Number_types/include/CGAL/long_double.h @@ -64,7 +64,7 @@ is_nan_by_mask_long_double(unsigned int h, unsigned int l) template<> class Is_valid< long double > - : public CGAL::unary_function< long double, bool > { + : public CGAL::cpp98::unary_function< long double, bool > { public : bool operator()( const long double& x ) const { double d = x; @@ -77,7 +77,7 @@ class Is_valid< long double > template<> class Is_valid< long double > - : public CGAL::unary_function< long double, bool > { + : public CGAL::cpp98::unary_function< long double, bool > { public : bool operator()( const long double& x ) const { return (x == x); @@ -97,7 +97,7 @@ template <> class Algebraic_structure_traits< long double > typedef Tag_true Is_numerical_sensitive; class Sqrt - : public CGAL::unary_function< Type, Type > { + : public CGAL::cpp98::unary_function< Type, Type > { public: Type operator()( const Type& x ) const { return std::sqrt( x ); @@ -105,7 +105,7 @@ template <> class Algebraic_structure_traits< long double > }; class Kth_root - :public CGAL::binary_function { + :public CGAL::cpp98::binary_function { public: Type operator()( int k, const Type& x) const { @@ -122,7 +122,7 @@ template <> class Real_embeddable_traits< long double > public: class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { // The conversion long double to double does not always follow the @@ -147,7 +147,7 @@ template <> class Real_embeddable_traits< long double > // Is_finite depends on platform class Is_finite - : public CGAL::unary_function< Type, bool > { + : public CGAL::cpp98::unary_function< Type, bool > { public: bool operator()( const Type& x ) const { #ifdef CGAL_CFG_IEEE_754_BUG diff --git a/Number_types/include/CGAL/long_long.h b/Number_types/include/CGAL/long_long.h index 36b8235aa3f..aeb318c1b2d 100644 --- a/Number_types/include/CGAL/long_long.h +++ b/Number_types/include/CGAL/long_long.h @@ -46,7 +46,7 @@ template<> class Algebraic_structure_traits< long long int > typedef INTERN_AST::Mod_per_operator< Type > Mod; class Is_square - : public CGAL::binary_function< Type, Type&, + : public CGAL::cpp98::binary_function< Type, Type&, bool > { public: bool operator()( const Type& x, @@ -67,7 +67,7 @@ template <> class Real_embeddable_traits< long long int > public: class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { return Interval_nt(x).pair(); @@ -81,7 +81,7 @@ template <> class Real_embeddable_traits< unsigned long long > public: class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { return Interval_nt(x).pair(); @@ -109,7 +109,7 @@ template <> class Real_embeddable_traits< boost::int128_type > public: class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { return (Interval_nt<>((double)x)+Interval_nt<>::smallest()).pair(); @@ -123,7 +123,7 @@ template <> class Real_embeddable_traits< boost::uint128_type > public: class To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { public: std::pair operator()( const Type& x ) const { return (Interval_nt<>((double)x)+Interval_nt<>::smallest()).pair(); diff --git a/Number_types/include/CGAL/mpq_class.h b/Number_types/include/CGAL/mpq_class.h index 8d739ce2c5c..ec3dbc9cdfd 100644 --- a/Number_types/include/CGAL/mpq_class.h +++ b/Number_types/include/CGAL/mpq_class.h @@ -57,7 +57,7 @@ class Algebraic_structure_traits< mpq_class > typedef Tag_true Is_exact; typedef Tag_false Is_numerical_sensitive; - struct Is_zero: public CGAL::unary_function< mpq_class , bool > { + struct Is_zero: public CGAL::cpp98::unary_function< mpq_class , bool > { template bool operator()( const ::__gmp_expr< T , U >& x) const { CGAL_CHECK_GMP_EXPR; @@ -65,7 +65,7 @@ class Algebraic_structure_traits< mpq_class > } }; - struct Is_one: public CGAL::unary_function< mpq_class , bool > { + struct Is_one: public CGAL::cpp98::unary_function< mpq_class , bool > { template bool operator()( const ::__gmp_expr< T , U >& x) const { CGAL_CHECK_GMP_EXPR; @@ -73,27 +73,27 @@ class Algebraic_structure_traits< mpq_class > } }; - struct Simplify: public CGAL::unary_function< mpq_class , void > { + struct Simplify: public CGAL::cpp98::unary_function< mpq_class , void > { void operator()( mpq_class& x) const { // do nothing because x is already canonical? x.canonicalize(); } }; - struct Square: public CGAL::unary_function< mpq_class , mpq_class > { + struct Square: public CGAL::cpp98::unary_function< mpq_class , mpq_class > { mpq_class operator()( const mpq_class& x) const { return x*x; } }; - struct Unit_part: public CGAL::unary_function< mpq_class , mpq_class > { + struct Unit_part: public CGAL::cpp98::unary_function< mpq_class , mpq_class > { mpq_class operator()( const mpq_class& x) const { return( x == 0) ? mpq_class(1) : x; } }; struct Integral_division - : public CGAL::binary_function< mpq_class , mpq_class, mpq_class > { + : public CGAL::cpp98::binary_function< mpq_class , mpq_class, mpq_class > { template mpq_class operator()( const ::__gmp_expr< T , U1 >& x, @@ -109,7 +109,7 @@ class Algebraic_structure_traits< mpq_class > }; class Is_square - : public CGAL::binary_function< mpq_class, mpq_class&, bool > { + : public CGAL::cpp98::binary_function< mpq_class, mpq_class&, bool > { public: bool operator()( const mpq_class& x, mpq_class& y ) const { y = mpq_class (::sqrt( x.get_num() ), ::sqrt( x.get_den() )) ; @@ -131,14 +131,14 @@ class Real_embeddable_traits< mpq_class > : public INTERN_RET::Real_embeddable_traits_base< mpq_class , CGAL::Tag_true > { public: - struct Is_zero: public CGAL::unary_function< mpq_class , bool > { + struct Is_zero: public CGAL::cpp98::unary_function< mpq_class , bool > { template bool operator()( const ::__gmp_expr< T , U >& x) const { CGAL_CHECK_GMP_EXPR; return ::sgn(x) == 0; } }; - struct Is_finite: public CGAL::unary_function { + struct Is_finite: public CGAL::cpp98::unary_function { template bool operator()( const ::__gmp_expr< T , U >&) const { CGAL_CHECK_GMP_EXPR; @@ -146,7 +146,7 @@ class Real_embeddable_traits< mpq_class > } }; - struct Is_positive: public CGAL::unary_function< mpq_class , bool > { + struct Is_positive: public CGAL::cpp98::unary_function< mpq_class , bool > { template bool operator()( const ::__gmp_expr< T , U >& x) const { CGAL_CHECK_GMP_EXPR; @@ -154,7 +154,7 @@ class Real_embeddable_traits< mpq_class > } }; - struct Is_negative: public CGAL::unary_function< mpq_class , bool > { + struct Is_negative: public CGAL::cpp98::unary_function< mpq_class , bool > { template bool operator()( const ::__gmp_expr< T , U >& x) const { CGAL_CHECK_GMP_EXPR; @@ -162,7 +162,7 @@ class Real_embeddable_traits< mpq_class > } }; - struct Abs: public CGAL::unary_function< mpq_class , mpq_class > { + struct Abs: public CGAL::cpp98::unary_function< mpq_class , mpq_class > { template mpq_class operator()( const ::__gmp_expr< T , U >& x) const { CGAL_CHECK_GMP_EXPR; @@ -171,7 +171,7 @@ class Real_embeddable_traits< mpq_class > }; struct Sgn - : public CGAL::unary_function< mpq_class, ::CGAL::Sign > { + : public CGAL::cpp98::unary_function< mpq_class, ::CGAL::Sign > { public: template ::CGAL::Sign @@ -182,7 +182,7 @@ class Real_embeddable_traits< mpq_class > }; struct Compare - : public CGAL::binary_function< mpq_class, mpq_class, Comparison_result> + : public CGAL::cpp98::binary_function< mpq_class, mpq_class, Comparison_result> { template Comparison_result operator()( @@ -197,7 +197,7 @@ class Real_embeddable_traits< mpq_class > }; struct To_double - : public CGAL::unary_function< mpq_class, double > { + : public CGAL::cpp98::unary_function< mpq_class, double > { double operator()( const mpq_class& x ) const { return x.get_d(); } @@ -205,13 +205,18 @@ class Real_embeddable_traits< mpq_class > struct To_interval - : public CGAL::unary_function< mpq_class, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< mpq_class, std::pair< double, double > > { std::pair operator()( const mpq_class& x ) const { #if MPFR_VERSION_MAJOR >= 3 + mpfr_exp_t emin = mpfr_get_emin(); + mpfr_set_emin(-1073); MPFR_DECL_INIT (y, 53); /* Assume IEEE-754 */ int r = mpfr_set_q (y, x.get_mpq_t(), MPFR_RNDA); + r = mpfr_subnormalize (y, r, MPFR_RNDA); /* Round subnormals */ double i = mpfr_get_d (y, MPFR_RNDA); /* EXACT but can overflow */ + mpfr_set_emin(emin); /* Restore old value, users may care */ + // With mpfr_set_emax(1024) we could drop the is_finite test if (r == 0 && is_finite (i)) return std::pair(i, i); else diff --git a/Number_types/include/CGAL/mpz_class.h b/Number_types/include/CGAL/mpz_class.h index bcdac926ab2..21aa543903a 100644 --- a/Number_types/include/CGAL/mpz_class.h +++ b/Number_types/include/CGAL/mpz_class.h @@ -58,7 +58,7 @@ public: typedef Tag_true Is_exact; typedef Tag_false Is_numerical_sensitive; - struct Is_zero: public CGAL::unary_function< mpz_class , bool > { + struct Is_zero: public CGAL::cpp98::unary_function< mpz_class , bool > { template bool operator()( const ::__gmp_expr< T , U >& x) const { CGAL_CHECK_GMP_EXPR; @@ -66,7 +66,7 @@ public: } }; - struct Is_one: public CGAL::unary_function< mpz_class , bool > { + struct Is_one: public CGAL::cpp98::unary_function< mpz_class , bool > { template bool operator()( const ::__gmp_expr< T , U >& x) const { CGAL_CHECK_GMP_EXPR; @@ -74,20 +74,20 @@ public: } }; - struct Simplify: public CGAL::unary_function< mpz_class , void > { + struct Simplify: public CGAL::cpp98::unary_function< mpz_class , void > { template void operator()( const ::__gmp_expr< T ,U >&) const { CGAL_CHECK_GMP_EXPR; } }; - struct Square: public CGAL::unary_function< mpz_class , mpz_class > { + struct Square: public CGAL::cpp98::unary_function< mpz_class , mpz_class > { mpz_class operator()( const mpz_class& x) const { return x*x; } }; - struct Unit_part: public CGAL::unary_function< mpz_class , mpz_class > { + struct Unit_part: public CGAL::cpp98::unary_function< mpz_class , mpz_class > { mpz_class operator()( const mpz_class& x) const { return (x < 0) ? -1 : 1; } @@ -96,7 +96,7 @@ public: struct Integral_division: - public CGAL::binary_function< mpz_class , mpz_class, mpz_class > { + public CGAL::cpp98::binary_function< mpz_class , mpz_class, mpz_class > { template mpz_class operator()( const ::__gmp_expr< T , U1 >& x, @@ -111,7 +111,7 @@ public: CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR( Type ) }; - struct Gcd : public CGAL::binary_function< mpz_class, mpz_class, mpz_class > { + struct Gcd : public CGAL::cpp98::binary_function< mpz_class, mpz_class, mpz_class > { mpz_class operator()( const mpz_class& x, const mpz_class& y) const { @@ -122,7 +122,7 @@ public: CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR( Type ) }; - struct Div : public CGAL::binary_function< mpz_class, mpz_class, mpz_class > { + struct Div : public CGAL::cpp98::binary_function< mpz_class, mpz_class, mpz_class > { template mpz_class operator()( const ::__gmp_expr< T , U1 >& x, @@ -133,7 +133,7 @@ public: CGAL_IMPLICIT_INTEROPERABLE_BINARY_OPERATOR( Type ) }; - struct Mod : public CGAL::binary_function< mpz_class, mpz_class, mpz_class > { + struct Mod : public CGAL::cpp98::binary_function< mpz_class, mpz_class, mpz_class > { template mpz_class operator()( const ::__gmp_expr< T , U1 >& x, @@ -166,7 +166,7 @@ public: }; - struct Sqrt: public CGAL::unary_function< mpz_class , mpz_class > { + struct Sqrt: public CGAL::cpp98::unary_function< mpz_class , mpz_class > { template mpz_class operator()( const ::__gmp_expr< T , U >& x) const { CGAL_CHECK_GMP_EXPR; @@ -175,7 +175,7 @@ public: }; - /*struct Is_square: public CGAL::binary_function< mpz_class , mpz_class& , bool > { + /*struct Is_square: public CGAL::cpp98::binary_function< mpz_class , mpz_class& , bool > { template bool operator()( const ::__gmp_expr< T , U >& x, @@ -197,14 +197,14 @@ class Real_embeddable_traits< mpz_class > : public INTERN_RET::Real_embeddable_traits_base< mpz_class , CGAL::Tag_true > { public: - struct Is_zero: public CGAL::unary_function< mpz_class , bool > { + struct Is_zero: public CGAL::cpp98::unary_function< mpz_class , bool > { template bool operator()( const ::__gmp_expr< T , U >& x) const { CGAL_CHECK_GMP_EXPR; return ::sgn(x) == 0; } }; - struct Is_finite: public CGAL::unary_function { + struct Is_finite: public CGAL::cpp98::unary_function { template bool operator()( const ::__gmp_expr< T , U >& ) const { CGAL_CHECK_GMP_EXPR; @@ -212,7 +212,7 @@ public: } }; - struct Is_positive: public CGAL::unary_function< mpz_class , bool > { + struct Is_positive: public CGAL::cpp98::unary_function< mpz_class , bool > { template bool operator()( const ::__gmp_expr< T , U >& x) const { CGAL_CHECK_GMP_EXPR; @@ -220,7 +220,7 @@ public: } }; - struct Is_negative: public CGAL::unary_function< mpz_class , bool > { + struct Is_negative: public CGAL::cpp98::unary_function< mpz_class , bool > { template bool operator()( const ::__gmp_expr< T , U >& x) const { CGAL_CHECK_GMP_EXPR; @@ -228,7 +228,7 @@ public: } }; - struct Abs: public CGAL::unary_function< mpz_class , mpz_class > { + struct Abs: public CGAL::cpp98::unary_function< mpz_class , mpz_class > { template mpz_class operator()( const ::__gmp_expr< T , U >& x) const { CGAL_CHECK_GMP_EXPR; @@ -237,7 +237,7 @@ public: }; struct Sgn - : public CGAL::unary_function< mpz_class, ::CGAL::Sign > { + : public CGAL::cpp98::unary_function< mpz_class, ::CGAL::Sign > { public: template ::CGAL::Sign operator()( const ::__gmp_expr< T , U >& x ) const { @@ -247,7 +247,7 @@ public: }; struct Compare - : public CGAL::binary_function< mpz_class, mpz_class, Comparison_result > { + : public CGAL::cpp98::binary_function< mpz_class, mpz_class, Comparison_result > { template Comparison_result operator()( const ::__gmp_expr< T , U1 >& x, @@ -261,7 +261,7 @@ public: }; struct To_double - : public CGAL::unary_function< mpz_class, double > { + : public CGAL::cpp98::unary_function< mpz_class, double > { double operator()( const mpz_class& x ) const { return x.get_d(); } @@ -269,7 +269,7 @@ public: struct To_interval - : public CGAL::unary_function< mpz_class, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< mpz_class, std::pair< double, double > > { std::pair operator()( const mpz_class& x ) const { #if MPFR_VERSION_MAJOR >= 3 diff --git a/Number_types/include/CGAL/utils_classes.h b/Number_types/include/CGAL/utils_classes.h index cbfc5a5d580..7f0c9c0188f 100644 --- a/Number_types/include/CGAL/utils_classes.h +++ b/Number_types/include/CGAL/utils_classes.h @@ -30,43 +30,43 @@ namespace CGAL { template < class A, class B = A > -struct Equal_to : public CGAL::binary_function< A, B, bool > { +struct Equal_to : public CGAL::cpp98::binary_function< A, B, bool > { bool operator()( const A& x, const B& y) const { return x == y; } }; template < class A, class B = A > -struct Not_equal_to : public CGAL::binary_function< A, B, bool > { +struct Not_equal_to : public CGAL::cpp98::binary_function< A, B, bool > { bool operator()( const A& x, const B& y) const { return x != y; } }; template < class A, class B = A > -struct Greater : public CGAL::binary_function< A, B, bool > { +struct Greater : public CGAL::cpp98::binary_function< A, B, bool > { bool operator()( const A& x, const B& y) const { return x > y; } }; template < class A, class B = A > -struct Less : public CGAL::binary_function< A, B, bool > { +struct Less : public CGAL::cpp98::binary_function< A, B, bool > { bool operator()( const A& x, const B& y) const { return x < y; } }; template < class A, class B = A > -struct Greater_equal : public CGAL::binary_function< A, B, bool > { +struct Greater_equal : public CGAL::cpp98::binary_function< A, B, bool > { bool operator()( const A& x, const B& y) const { return x >= y; } }; template < class A, class B = A > -struct Less_equal : public CGAL::binary_function< A, B, bool > { +struct Less_equal : public CGAL::cpp98::binary_function< A, B, bool > { bool operator()( const A& x, const B& y) const { return x <= y; } }; template < class NT, class Less = std::less< NT > > -struct Min :public CGAL::binary_function< NT, NT, NT > { +struct Min :public CGAL::cpp98::binary_function< NT, NT, NT > { Min() {} Min(const Less& c_) : c(c_) {} NT operator()( const NT& x, const NT& y) const @@ -76,7 +76,7 @@ protected: }; template < class NT, class Less = std::less< NT > > -struct Max :public CGAL::binary_function< NT, NT, NT > { +struct Max :public CGAL::cpp98::binary_function< NT, NT, NT > { Max() {} Max(const Less& c_) : c(c_) {} NT operator()( const NT& x, const NT& y) const @@ -201,7 +201,7 @@ inline void sse2minmax(double& a, double b, double& c) #endif // CGAL_USE_SSE2_MAX template <> -struct Max :public CGAL::binary_function< double, double, double > { +struct Max :public CGAL::cpp98::binary_function< double, double, double > { Max() {} double operator()( const double& x, const double& y) const @@ -233,7 +233,7 @@ struct Max :public CGAL::binary_function< double, double, double > { }; template <> -struct Min :public CGAL::binary_function< double, double, double > { +struct Min :public CGAL::cpp98::binary_function< double, double, double > { Min() {} double operator()( const double& x, const double& y) const @@ -265,7 +265,7 @@ struct Min :public CGAL::binary_function< double, double, double > { }; template< class T > class Is_valid - : public CGAL::unary_function< T, bool > { + : public CGAL::cpp98::unary_function< T, bool > { public: bool operator()( const T& ) const { return true; diff --git a/Number_types/test/Number_types/Gmpq.cpp b/Number_types/test/Number_types/Gmpq.cpp index f0b694e3785..f4d84e490d7 100644 --- a/Number_types/test/Number_types/Gmpq.cpp +++ b/Number_types/test/Number_types/Gmpq.cpp @@ -36,6 +36,20 @@ void test_overflow_to_interval(const NT&) } } +template +void test_underflow_to_interval(const NT&) +{ + NT q0 = std::numeric_limits::denorm_min(); + NT q1 = q0 / 2; + NT q2 = q1 * 3; + CGAL::Interval_nt<> i1 = CGAL::to_interval(q1); + CGAL::Interval_nt<> i2 = CGAL::to_interval(q2); + assert(i1.inf() <= q1); + assert(i1.sup() >= q1); + assert(i2.inf() <= q2); + assert(i2.sup() >= q2); +} + void test_overflow_to_double() { std::cout << "Tests if to_double(Gmpq) overflows or not." << std::endl; @@ -263,10 +277,12 @@ int main() { test_overflow_to_double(); test_overflow_to_interval(Gmpz()); test_overflow_to_interval(Gmpq()); + test_underflow_to_interval(Gmpq()); #ifdef CGAL_USE_GMPXX test_overflow_to_interval(mpz_class()); test_overflow_to_interval(mpq_class()); + test_underflow_to_interval(mpq_class()); #endif // test operators Gmpq/Gmpfr (added by Luis) diff --git a/Number_types/test/Number_types/checked_NT.h b/Number_types/test/Number_types/checked_NT.h index 75fcbe33f8e..fd00a2da0f3 100644 --- a/Number_types/test/Number_types/checked_NT.h +++ b/Number_types/test/Number_types/checked_NT.h @@ -48,7 +48,7 @@ template struct Algebraic_structure_traits Type; struct Is_zero - : public CGAL::unary_function< Type, bool > { + : public CGAL::cpp98::unary_function< Type, bool > { bool operator()( const Type& x ) const { bool a=CGAL::is_zero(x.x1); bool b=CGAL::is_zero(x.x2); @@ -57,7 +57,7 @@ template struct Algebraic_structure_traits { + : public CGAL::cpp98::unary_function< Type, bool > { bool operator()( const Type& x ) const { bool a=CGAL::is_one(x.x1); bool b=CGAL::is_one(x.x2); @@ -66,7 +66,7 @@ template struct Algebraic_structure_traits { + : public CGAL::cpp98::unary_function< Type, bool > { bool operator()( const Type& x ) const { bool a=CGAL::is_square(x.x1); bool b=CGAL::is_square(x.x2); @@ -75,13 +75,13 @@ template struct Algebraic_structure_traits { + : public CGAL::cpp98::unary_function< Type, Type > { Type operator()( const Type& x ) const { return Type(typename Type::pieces(),CGAL::square(x.x1),CGAL::square(x.x2)); } }; struct Div - : public CGAL::binary_function< Type, Type, Type > { + : public CGAL::cpp98::binary_function< Type, Type, Type > { Type operator()( const Type& x, const Type& y ) const { return Type(typename Type::pieces(), CGAL::div(x.x1,y.x1), @@ -89,7 +89,7 @@ template struct Algebraic_structure_traits { + : public CGAL::cpp98::binary_function< Type, Type, Type > { Type operator()( const Type& x, const Type& y ) const { return Type(typename Type::pieces(), CGAL::mod(x.x1,y.x1), @@ -97,7 +97,7 @@ template struct Algebraic_structure_traits { + : public CGAL::cpp98::binary_function< Type, Type, Type > { Type operator()( const Type& x, const Type& y ) const { return Type(typename Type::pieces(), CGAL::integral_division(x.x1,y.x1), @@ -110,7 +110,7 @@ templatestruct Real_embeddable_traits > : INTERN_RET::Real_embeddable_traits_base, typename Real_embeddable_traits::Is_real_embeddable> { typedef checked_NT Type; struct Sgn - : public CGAL::unary_function< Type, ::CGAL::Sign > { + : public CGAL::cpp98::unary_function< Type, ::CGAL::Sign > { ::CGAL::Sign operator()( const Type& x ) const { ::CGAL::Sign a=CGAL::sign(x.x1); ::CGAL::Sign b=CGAL::sign(x.x2); @@ -119,19 +119,19 @@ templatestruct Real_embeddable_traits > } }; struct To_double - : public CGAL::unary_function< Type, double > { + : public CGAL::cpp98::unary_function< Type, double > { double operator()( const Type& x ) const { return x.to_double(); } }; struct To_interval - : public CGAL::unary_function< Type, std::pair< double, double > > { + : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { std::pair operator()( const Type& x ) const { return x.to_interval(); } }; struct Compare - : public CGAL::binary_function< Type, Type, Comparison_result > { + : public CGAL::cpp98::binary_function< Type, Type, Comparison_result > { Comparison_result operator()( const Type& x, const Type& y ) const { diff --git a/Optimal_transportation_reconstruction_2/demo/Optimal_transportation_reconstruction_2/scene.h b/Optimal_transportation_reconstruction_2/demo/Optimal_transportation_reconstruction_2/scene.h index b65e28ab038..4a9d9c8f73b 100644 --- a/Optimal_transportation_reconstruction_2/demo/Optimal_transportation_reconstruction_2/scene.h +++ b/Optimal_transportation_reconstruction_2/demo/Optimal_transportation_reconstruction_2/scene.h @@ -83,7 +83,7 @@ public: private: - struct Point_3_from_sample : public CGAL::unary_function + struct Point_3_from_sample : public CGAL::cpp98::unary_function { K::Point_3 operator() (const Sample_& sample) const { diff --git a/Partition_2/include/CGAL/Partition_2/Rotation_tree_2.h b/Partition_2/include/CGAL/Partition_2/Rotation_tree_2.h index f9228e36d0b..a149a137f06 100644 --- a/Partition_2/include/CGAL/Partition_2/Rotation_tree_2.h +++ b/Partition_2/include/CGAL/Partition_2/Rotation_tree_2.h @@ -36,6 +36,8 @@ #ifndef CGAL_ROTATION_TREE_H #define CGAL_ROTATION_TREE_H +#include + #include @@ -178,6 +180,8 @@ private: #include +#include + #endif // CGAL_ROTATION_TREE_H // For the Emacs editor: diff --git a/Periodic_2_triangulation_2/examples/Periodic_2_triangulation_2/p2t2_info_insert_with_transform_iterator_2.cpp b/Periodic_2_triangulation_2/examples/Periodic_2_triangulation_2/p2t2_info_insert_with_transform_iterator_2.cpp index 223fc38446e..79097940a19 100644 --- a/Periodic_2_triangulation_2/examples/Periodic_2_triangulation_2/p2t2_info_insert_with_transform_iterator_2.cpp +++ b/Periodic_2_triangulation_2/examples/Periodic_2_triangulation_2/p2t2_info_insert_with_transform_iterator_2.cpp @@ -19,7 +19,7 @@ typedef Delaunay::Point Point; //the unsigned integer is incremented at each call to //operator() struct Auto_count - : public CGAL::unary_function > + : public CGAL::cpp98::unary_function > { mutable unsigned i; Auto_count() : i(0) {} diff --git a/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/CMakeLists.txt b/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/CMakeLists.txt index 47b911088b6..ed5aad38c95 100644 --- a/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/CMakeLists.txt +++ b/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/CMakeLists.txt @@ -17,15 +17,12 @@ include( ${CGAL_USE_FILE} ) # Find Qt5 itself find_package(Qt5 QUIET COMPONENTS Xml OpenGL Help Core) -# Find QGLViewer + if(Qt5_FOUND) add_definitions(-DQT_NO_KEYWORDS) - find_package(QGLViewer) endif(Qt5_FOUND) -if (CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND AND TARGET Qt5::qcollectiongenerator) - - include_directories( ${QGLVIEWER_INCLUDE_DIR} ) +if (CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND TARGET Qt5::qcollectiongenerator) # UI files (Qt Designer files) qt5_wrap_ui ( UI_FILES MainWindow.ui ) @@ -67,7 +64,7 @@ if (CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND AND TARGET Q add_to_cached_list( CGAL_EXECUTABLE_TARGETS periodic_3_triangulation_3_demo) target_link_libraries(periodic_3_triangulation_3_demo PRIVATE - CGAL::CGAL CGAL::CGAL_Qt5 Qt5::OpenGL ${QGLVIEWER_LIBRARIES}) + CGAL::CGAL CGAL::CGAL_Qt5 Qt5::OpenGL) include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake) cgal_add_compilation_test(periodic_3_triangulation_3_demo) @@ -83,10 +80,6 @@ else () set(PERIODIC_TRIANGULATION_MISSING_DEPS "Qt5, ${PERIODIC_TRIANGULATION_MISSING_DEPS}") endif() - if(NOT QGLVIEWER_FOUND) - set(PERIODIC_TRIANGULATION_MISSING_DEPS "QGLViewer, ${PERIODIC_TRIANGULATION_MISSING_DEPS}") - endif() - if (NOT TARGET Qt5::qcollectiongenerator) set(PERIODIC_TRIANGULATION_MISSING_DEPS "qcollectiongenerator, ${PERIODIC_TRIANGULATION_MISSING_DEPS}") endif() diff --git a/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/MainWindow.h b/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/MainWindow.h index eb40c51f6c2..439972c45a8 100644 --- a/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/MainWindow.h +++ b/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/MainWindow.h @@ -23,7 +23,7 @@ public: process = new QProcess(this); - // QGLViewer drawing signals + // CGAL::QGLViewer drawing signals connect(ui->viewer, SIGNAL(viewerInitialized()), s, SLOT(init())); connect(ui->viewer, SIGNAL(drawNeeded()), s, SLOT(draw())); @@ -59,8 +59,8 @@ public: s, SLOT(insert_random())); connect(ui->actionGrab_image, SIGNAL(triggered()), - s, SLOT(grab_image())); - + s, SLOT(grab_image())); + // Features menu: connect(ui->actionPoint_location, SIGNAL(toggled(bool)), s, SLOT(toggle_dlocate(bool))); diff --git a/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/Scene.cpp b/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/Scene.cpp index 388af96c2e9..47f483d2f38 100644 --- a/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/Scene.cpp +++ b/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/Scene.cpp @@ -289,7 +289,7 @@ void Scene::compute_elements() if(std::sqrt(CGAL_NTS to_double(v.x()*v.x()+v.y()*v.y())) > 1) angle = 90.0f; else - angle =acos(v.y()/std::sqrt(v.x()*v.x()+v.y()*v.y()+v.z()*v.z()))*180.0/M_PI;//asin(std::sqrt(CGAL_NTS to_double(v.x()*v.x()+v.y()*v.y())))/M_PI*180.0; + angle =acos(v.y()/std::sqrt(v.x()*v.x()+v.y()*v.y()+v.z()*v.z()))*180.0/CGAL_PI;//asin(std::sqrt(CGAL_NTS to_double(v.x()*v.x()+v.y()*v.y())))/CGAL_PI*180.0; Vector axis; axis = Vector(v.z(), 0, -v.x()); @@ -695,7 +695,7 @@ void Scene::initialize_buffers() } -void Scene::attrib_buffers(QGLViewer* viewer) +void Scene::attrib_buffers(CGAL::QGLViewer* viewer) { QMatrix4x4 mvpMatrix; QMatrix4x4 mvMatrix; @@ -762,7 +762,7 @@ void Scene::attrib_buffers(QGLViewer* viewer) } void Scene::init() { - // undo from QGLViewer internal initializeGL function + // undo from CGAL::QGLViewer internal initializeGL function // glDisable(GL_COLOR_MATERIAL); initializeOpenGLFunctions(); glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDARBPROC)ui->viewer->context()->getProcAddress("glDrawArraysInstancedARB"); @@ -790,7 +790,7 @@ void Scene::init() { ui->viewer->camera()->lookAt(Vec(0.5,0.5,0.5)); // scene inits - ui->viewer->setSceneCenter(qglviewer::Vec(0.5,0.5,0.5)); + ui->viewer->setSceneCenter(CGAL::qglviewer::Vec(0.5,0.5,0.5)); ui->viewer->setSceneRadius(2.0); ui->viewer->setBackgroundColor(Qt::white); ui->viewer->setForegroundColor(Qt::red); @@ -1717,8 +1717,8 @@ void Scene::draw_sphere(float R, int prec) - P = rings*M_PI/180.0; - T = t*M_PI/180.0; + P = rings*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[1] = sin(P) * cos(T) ; y[1] = sin(P) * sin(T) ; z[1] = cos(P); @@ -1732,8 +1732,8 @@ void Scene::draw_sphere(float R, int prec) normals_spheres.push_back(z[1]); // - P = rings*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = rings*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[2] = sin(P) * cos(T) ; y[2] = sin(P) * sin(T) ; z[2] = cos(P); @@ -1752,8 +1752,8 @@ void Scene::draw_sphere(float R, int prec) for(int t=0; t<360; t+=sectors) { //A - P = p*M_PI/180.0; - T = t*M_PI/180.0; + P = p*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[0] = sin(P) * cos(T) ; y[0] = sin(P) * sin(T) ; z[0] = cos(P); @@ -1768,8 +1768,8 @@ void Scene::draw_sphere(float R, int prec) normals_spheres.push_back(z[0]); //B - P = (p+rings)*M_PI/180.0; - T = t*M_PI/180.0; + P = (p+rings)*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[1] = sin(P) * cos(T) ; y[1] = sin(P) * sin(T) ; z[1] = cos(P); @@ -1783,8 +1783,8 @@ void Scene::draw_sphere(float R, int prec) normals_spheres.push_back(z[1]); //C - P = p*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = p*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[2] = sin(P) * cos(T) ; y[2] = sin(P) * sin(T) ; z[2] = cos(P); @@ -1797,8 +1797,8 @@ void Scene::draw_sphere(float R, int prec) normals_spheres.push_back(y[2]); normals_spheres.push_back(z[2]); //D - P = (p+rings)*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = (p+rings)*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[3] = sin(P) * cos(T) ; y[3] = sin(P) * sin(T) ; z[3] = cos(P); @@ -1847,8 +1847,8 @@ void Scene::draw_sphere(float R, int prec) normals_spheres.push_back(-1); - P = (180-rings)*M_PI/180.0; - T = t*M_PI/180.0; + P = (180-rings)*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[1] = sin(P) * cos(T) ; y[1] = sin(P) * sin(T) ; z[1] = cos(P); @@ -1862,8 +1862,8 @@ void Scene::draw_sphere(float R, int prec) normals_spheres.push_back(z[1]); - P = (180-rings)*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = (180-rings)*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[2] = sin(P) * cos(T) ; y[2] = sin(P) * sin(T) ; z[2] = cos(P); @@ -1902,8 +1902,8 @@ void Scene::draw_cylinder(float R, int prec, std::vector *vertices, std:: - P = rings*M_PI/180.0; - T = t*M_PI/180.0; + P = rings*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[1] = sin(P) * cos(T) ; z[1] = sin(P) * sin(T) ; y[1] = cos(P); @@ -1917,8 +1917,8 @@ void Scene::draw_cylinder(float R, int prec, std::vector *vertices, std:: normals->push_back(z[1]); // - P = rings*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = rings*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[2] = sin(P) * cos(T) ; z[2] = sin(P) * sin(T) ; y[2] = cos(P); @@ -1936,8 +1936,8 @@ void Scene::draw_cylinder(float R, int prec, std::vector *vertices, std:: for(int t=0; t<360; t+=sectors) { //A - P = p*M_PI/180.0; - T = t*M_PI/180.0; + P = p*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[0] = sin(P) * cos(T) ; z[0] = sin(P) * sin(T) ; y[0] = cos(P); @@ -1952,8 +1952,8 @@ void Scene::draw_cylinder(float R, int prec, std::vector *vertices, std:: normals->push_back(z[0]); //B - P = (p+rings)*M_PI/180.0; - T = t*M_PI/180.0; + P = (p+rings)*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[1] = sin(P) * cos(T) ; z[1] = sin(P) * sin(T) ; y[1] = cos(P); @@ -1967,8 +1967,8 @@ void Scene::draw_cylinder(float R, int prec, std::vector *vertices, std:: normals->push_back(z[1]); //C - P = p*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = p*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[2] = sin(P) * cos(T) ; z[2] = sin(P) * sin(T) ; y[2] = cos(P); @@ -1981,8 +1981,8 @@ void Scene::draw_cylinder(float R, int prec, std::vector *vertices, std:: normals->push_back(y[2]); normals->push_back(z[2]); //D - P = (p+rings)*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = (p+rings)*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[3] = sin(P) * cos(T) ; z[3] = sin(P) * sin(T) ; y[3] = cos(P); @@ -2023,7 +2023,7 @@ void Scene::draw_cylinder(float R, int prec, std::vector *vertices, std:: { //point A1 - float D = d*M_PI/180.0; + float D = d*CGAL_PI/180.0; vertices->push_back(R * sin(D)); vertices->push_back(0); vertices->push_back(R * cos(D)); @@ -2042,7 +2042,7 @@ void Scene::draw_cylinder(float R, int prec, std::vector *vertices, std:: normals->push_back(cos(D)); //point C1 - D = (d+360/prec)*M_PI/180.0; + D = (d+360/prec)*CGAL_PI/180.0; vertices->push_back(R * sin(D)); vertices->push_back(1); vertices->push_back(R * cos(D)); @@ -2052,7 +2052,7 @@ void Scene::draw_cylinder(float R, int prec, std::vector *vertices, std:: normals->push_back(cos(D)); //point A2 - D = (d+360/prec)*M_PI/180.0; + D = (d+360/prec)*CGAL_PI/180.0; vertices->push_back(R * sin(D)); vertices->push_back(1); vertices->push_back(R * cos(D)); @@ -2071,7 +2071,7 @@ void Scene::draw_cylinder(float R, int prec, std::vector *vertices, std:: normals->push_back(cos(D)); //point C2 - D = d*M_PI/180.0; + D = d*CGAL_PI/180.0; vertices->push_back(R * sin(D)); vertices->push_back(0); vertices->push_back(R * cos(D)); @@ -2097,8 +2097,8 @@ void Scene::draw_cylinder(float R, int prec, std::vector *vertices, std:: - P = rings*M_PI/180.0; - T = t*M_PI/180.0; + P = rings*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[1] = sin(P) * cos(T) ; z[1] = sin(P) * sin(T) ; y[1] = cos(P); @@ -2112,8 +2112,8 @@ void Scene::draw_cylinder(float R, int prec, std::vector *vertices, std:: normals->push_back(z[1]); // - P = rings*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = rings*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[2] = sin(P) * cos(T) ; z[2] = sin(P) * sin(T) ; y[2] = cos(P); @@ -2131,8 +2131,8 @@ void Scene::draw_cylinder(float R, int prec, std::vector *vertices, std:: for(int t=0; t<360; t+=sectors) { //A - P = p*M_PI/180.0; - T = t*M_PI/180.0; + P = p*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[0] = sin(P) * cos(T) ; z[0] = sin(P) * sin(T) ; y[0] = cos(P); @@ -2147,8 +2147,8 @@ void Scene::draw_cylinder(float R, int prec, std::vector *vertices, std:: normals->push_back(z[0]); //B - P = (p+rings)*M_PI/180.0; - T = t*M_PI/180.0; + P = (p+rings)*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[1] = sin(P) * cos(T) ; z[1] = sin(P) * sin(T) ; y[1] = cos(P); @@ -2162,8 +2162,8 @@ void Scene::draw_cylinder(float R, int prec, std::vector *vertices, std:: normals->push_back(z[1]); //C - P = p*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = p*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[2] = sin(P) * cos(T) ; z[2] = sin(P) * sin(T) ; y[2] = cos(P); @@ -2176,8 +2176,8 @@ void Scene::draw_cylinder(float R, int prec, std::vector *vertices, std:: normals->push_back(y[2]); normals->push_back(z[2]); //D - P = (p+rings)*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = (p+rings)*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[3] = sin(P) * cos(T) ; z[3] = sin(P) * sin(T) ; y[3] = cos(P); diff --git a/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/Scene.h b/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/Scene.h index 6fddede666a..296d1bc5427 100644 --- a/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/Scene.h +++ b/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/Scene.h @@ -16,7 +16,7 @@ class Scene : public QObject, QOpenGLFunctions_2_1 Q_OBJECT private: - typedef qglviewer::Vec Vec; + typedef CGAL::qglviewer::Vec Vec; typedef std::set > Segment_set; enum Init {EMPTY, GRID, SINGLE, PLANE, RANDOM}; @@ -130,10 +130,11 @@ public Q_SLOTS: dconflict = temp_flags[1]; changed(); } + void grab_image() { - ui->viewer->openSnapshotFormatDialog(); - ui->viewer->saveSnapshot(false); + ui->viewer->saveSnapshot(); } + void toggle_dlocate(bool on) { dlocate = on; changed(); @@ -304,7 +305,7 @@ private: PFNGLVERTEXATTRIBDIVISORARBPROC glVertexAttribDivisor; void initialize_buffers(); void compute_elements(); - void attrib_buffers(QGLViewer*); + void attrib_buffers(CGAL::QGLViewer*); void compile_shaders(); void draw_sphere(float R, int prec); void draw_cylinder(float R, int prec, std::vector *vertices, std::vector *normals); diff --git a/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/Viewer.cpp b/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/Viewer.cpp index 51521874203..9fb7a2ea25f 100644 --- a/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/Viewer.cpp +++ b/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/Viewer.cpp @@ -2,7 +2,7 @@ #include Viewer::Viewer(QWidget *parent) -: QGLViewer(CGAL::Qt::createOpenGLContext(),parent) +: CGAL::QGLViewer(parent) {} Viewer::~Viewer() {} diff --git a/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/Viewer.h b/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/Viewer.h index 0badeb0aa14..c5bcbf9993e 100644 --- a/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/Viewer.h +++ b/Periodic_3_triangulation_3/demo/Periodic_3_triangulation_3/Viewer.h @@ -1,9 +1,9 @@ #ifndef VIEWER_H #define VIEWER_H #include -#include +#include -class Viewer : public QGLViewer{ +class Viewer : public CGAL::QGLViewer{ Q_OBJECT public: diff --git a/Periodic_3_triangulation_3/demo/Periodic_Lloyd_3/CMakeLists.txt b/Periodic_3_triangulation_3/demo/Periodic_Lloyd_3/CMakeLists.txt index ac6c2b0021d..d711a8dd6c7 100644 --- a/Periodic_3_triangulation_3/demo/Periodic_Lloyd_3/CMakeLists.txt +++ b/Periodic_3_triangulation_3/demo/Periodic_Lloyd_3/CMakeLists.txt @@ -23,14 +23,9 @@ include(${CGAL_USE_FILE}) find_package(Qt5 QUIET COMPONENTS Xml Script Help OpenGL Svg) -if(Qt5_FOUND) - find_package(QGLViewer) -endif(Qt5_FOUND) -if ( CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND AND TARGET Qt5::qcollectiongenerator ) +if ( CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND TARGET Qt5::qcollectiongenerator ) - - include_directories (${QGLVIEWER_INCLUDE_DIR}) include_directories (BEFORE ../../include ./ ) # ui file, created wih Qt Designer @@ -59,12 +54,11 @@ if ( CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND AND TARGET add_to_cached_list( CGAL_EXECUTABLE_TARGETS Periodic_Lloyd_3 ) target_link_libraries( Periodic_Lloyd_3 PRIVATE - CGAL::CGAL CGAL::CGAL_Qt5 Qt5::OpenGL - ${QGLVIEWER_LIBRARIES} ) + CGAL::CGAL CGAL::CGAL_Qt5 Qt5::OpenGL) include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake) cgal_add_compilation_test(Periodic_Lloyd_3) -else( CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND AND QT_QCOLLECTIONGENERATOR_EXECUTABLE ) +else( CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND QT_QCOLLECTIONGENERATOR_EXECUTABLE ) set(PERIODIC_LLOYD_MISSING_DEPS "") @@ -76,10 +70,6 @@ else( CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND AND QT_QCO set(PERIODIC_LLOYD_MISSING_DEPS "Qt5, ${PERIODIC_LLOYD_MISSING_DEPS}") endif() - if(NOT QGLVIEWER_FOUND) - set(PERIODIC_LLOYD_MISSING_DEPS "QGLViewer, ${PERIODIC_LLOYD_MISSING_DEPS}") - endif() - if(NOT QT_QCOLLECTIONGENERATOR_EXECUTABLE) set(PERIODIC_LLOYD_MISSING_DEPS "qcollectiongenerator, ${PERIODIC_LLOYD_MISSING_DEPS}") endif() diff --git a/Periodic_3_triangulation_3/demo/Periodic_Lloyd_3/MainWindow.cpp b/Periodic_3_triangulation_3/demo/Periodic_Lloyd_3/MainWindow.cpp index 9faad58a0da..6fd19cdf7c9 100644 --- a/Periodic_3_triangulation_3/demo/Periodic_Lloyd_3/MainWindow.cpp +++ b/Periodic_3_triangulation_3/demo/Periodic_Lloyd_3/MainWindow.cpp @@ -121,7 +121,7 @@ MainWindow::loadPoints() cy += dom[i].y(); cy += dom[i].y(); } - qglviewer::Vec center(cx/8.,cy/8.,cz/8.); + CGAL::qglviewer::Vec center(cx/8.,cy/8.,cz/8.); viewer->setSceneCenter(center); viewer->setSceneRadius(std::sqrt( ((dom.xmax()-dom.xmin())*(dom.xmax()-dom.xmin())) @@ -150,11 +150,7 @@ MainWindow::savePoints() void MainWindow::lloydStep() { scene.lloyd_step(); -#if QGLVIEWER_VERSION >= 0x020700 viewer->update(); -#else - viewer->updateGL(); -#endif viewer->changed(); } @@ -194,7 +190,7 @@ MainWindow::newPoints(int n) cy += dom[i].y(); cy += dom[i].y(); } - qglviewer::Vec center(cx/8.,cy/8.,cz/8.); + CGAL::qglviewer::Vec center(cx/8.,cy/8.,cz/8.); viewer->setSceneCenter(center); viewer->setSceneRadius(std::sqrt( ((dom.xmax()-dom.xmin())*(dom.xmax()-dom.xmin())) diff --git a/Periodic_3_triangulation_3/demo/Periodic_Lloyd_3/MainWindow.ui b/Periodic_3_triangulation_3/demo/Periodic_Lloyd_3/MainWindow.ui index 2be4acad50e..314ede5aa66 100644 --- a/Periodic_3_triangulation_3/demo/Periodic_Lloyd_3/MainWindow.ui +++ b/Periodic_3_triangulation_3/demo/Periodic_Lloyd_3/MainWindow.ui @@ -1,7 +1,8 @@ - + + MainWindow - - + + 0 0 @@ -9,57 +10,57 @@ 504 - + CGAL 3D Periodic Lloyd - - + + :/cgal/logos/cgal_icon:/cgal/logos/cgal_icon - - + + - + - - - + + + 0 0 - + 75 true - + Speed: - - - + + + 0 0 - + 0 - + 100 - + 1 - + 100 - + Qt::Horizontal @@ -67,184 +68,183 @@ - + - - + + 0 0 635 - 22 + 20 - - + + File - - - - - - - + + + + + + - - + + Control - - - - - + + + + + - - + + Help - + - - - + + + - - - + + + toolBar - + TopToolBarArea - + false - - - - - - - - - + + + + + + + + + - - + + Quit - - + + false - + Render Video - - - + + + :/Periodic_Lloyd_3/icons/fileNew.png:/Periodic_Lloyd_3/icons/fileNew.png - + New Point Set - + Ctrl+N - - + + true - + false - - + + :/Periodic_Lloyd_3/icons/play.png :/Periodic_Lloyd_3/icons/pause.png:/Periodic_Lloyd_3/icons/play.png - + Stop - + P - - + + true - - + + :/Periodic_Lloyd_3/icons/cp8.png:/Periodic_Lloyd_3/icons/cp8.png - + Show 8 Copies - + C - - + + true - - + + :/Periodic_Lloyd_3/icons/planar.png:/Periodic_Lloyd_3/icons/planar.png - + 2D version - + 2 - - - + + + :/Periodic_Lloyd_3/icons/step.png:/Periodic_Lloyd_3/icons/step.png - + Step - + Return, Enter - - - + + + :/Periodic_Lloyd_3/icons/fileOpen.png:/Periodic_Lloyd_3/icons/fileOpen.png - + Load points - + Ctrl+O - - - + + + :/Periodic_Lloyd_3/icons/fileSave.png:/Periodic_Lloyd_3/icons/fileSave.png - + Save points - + Ctrl+S - - + + Demo Help @@ -257,8 +257,10 @@ - - + + + + diff --git a/Periodic_3_triangulation_3/demo/Periodic_Lloyd_3/Viewer.cpp b/Periodic_3_triangulation_3/demo/Periodic_Lloyd_3/Viewer.cpp index 0acffda59df..bdaaf5bcad4 100644 --- a/Periodic_3_triangulation_3/demo/Periodic_Lloyd_3/Viewer.cpp +++ b/Periodic_3_triangulation_3/demo/Periodic_Lloyd_3/Viewer.cpp @@ -1,7 +1,7 @@ #include "Viewer.h" #include #include -#include +#include void @@ -10,8 +10,8 @@ Viewer::init() initializeOpenGLFunctions(); setBackgroundColor(::Qt::white); this->camera()->setSceneBoundingBox( - qglviewer::Vec(-1.,-1.,-1.), - qglviewer::Vec( 1., 1., 1.)); + CGAL::qglviewer::Vec(-1.,-1.,-1.), + CGAL::qglviewer::Vec( 1., 1., 1.)); glEnable(GL_LINE_SMOOTH); compile_shaders(); are_buffers_initialized = false; @@ -104,29 +104,6 @@ Viewer::next_around_circle(const float& phi, const Vec& pos, const Vec& ori) { return new_cam; } -void -Viewer::render_video() -{ - setSnapshotFormat("PNG"); - for (int alpha=0 ; alpha <= 100 ; alpha++ ) { - emit (valueChanged(alpha)); - std::cout<position(); - Vec ori = sceneCenter(); - Vec new_cam = next_around_circle(0.01f,cam,ori); - camera()->setPosition(new_cam); - camera()->lookAt(ori); - this->showEntireScene(); - saveSnapshot(true); - } - } -} - void Viewer::initialize_buffers() { rendering_program.bind(); @@ -233,7 +210,7 @@ void Viewer::compute_elements() } } -void Viewer::attrib_buffers(QGLViewer* viewer) +void Viewer::attrib_buffers(CGAL::QGLViewer* viewer) { QMatrix4x4 mvpMatrix; double mat[16]; diff --git a/Periodic_3_triangulation_3/demo/Periodic_Lloyd_3/Viewer.h b/Periodic_3_triangulation_3/demo/Periodic_Lloyd_3/Viewer.h index b794e34a306..dcc26348d41 100644 --- a/Periodic_3_triangulation_3/demo/Periodic_Lloyd_3/Viewer.h +++ b/Periodic_3_triangulation_3/demo/Periodic_Lloyd_3/Viewer.h @@ -3,7 +3,7 @@ #include "Scene.h" #include -#include +#include #include #include #include @@ -11,9 +11,9 @@ #include -class Viewer : public QGLViewer, QOpenGLFunctions_2_1 { +class Viewer : public CGAL::QGLViewer{ - typedef qglviewer::Vec Vec; + typedef CGAL::qglviewer::Vec Vec; Q_OBJECT @@ -23,7 +23,7 @@ class Viewer : public QGLViewer, QOpenGLFunctions_2_1 { int nr_of_facets; public: Viewer(QWidget* parent) - : QGLViewer(CGAL::Qt::createOpenGLContext(), parent) + : CGAL::QGLViewer(parent) {} ~Viewer() { @@ -49,7 +49,6 @@ public: public slots : void changed(); void sceneChanged(); - void render_video(); signals: void valueChanged(int i); @@ -73,7 +72,7 @@ private: QOpenGLShaderProgram rendering_program; void initialize_buffers(); void compute_elements(); - void attrib_buffers(QGLViewer*); + void attrib_buffers(CGAL::QGLViewer*); void compile_shaders(); }; diff --git a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_regular_triangulation_3.h b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_regular_triangulation_3.h index 14a7419274c..88f1049e1fe 100644 --- a/Periodic_3_triangulation_3/include/CGAL/Periodic_3_regular_triangulation_3.h +++ b/Periodic_3_triangulation_3/include/CGAL/Periodic_3_regular_triangulation_3.h @@ -187,7 +187,7 @@ public: private: struct Cell_handle_hash - : public CGAL::unary_function + : public CGAL::cpp98::unary_function { std::size_t operator()(const Cell_handle& ch) const { return boost::hash()(&*ch); diff --git a/Point_set_processing_3/examples/Point_set_processing_3/CMakeLists.txt b/Point_set_processing_3/examples/Point_set_processing_3/CMakeLists.txt index 2712f080b1c..1950f28e20e 100644 --- a/Point_set_processing_3/examples/Point_set_processing_3/CMakeLists.txt +++ b/Point_set_processing_3/examples/Point_set_processing_3/CMakeLists.txt @@ -42,7 +42,7 @@ if ( CGAL_FOUND ) endif() # Executables that do *not* require EIGEN or LAPACK - create_single_source_cgal_program( "average_spacing_example.cpp" ) + create_single_source_cgal_program( "average_spacing_example.cpp" ) create_single_source_cgal_program( "bilateral_smooth_point_set_example.cpp" ) create_single_source_cgal_program( "grid_simplification_example.cpp" ) create_single_source_cgal_program( "grid_simplify_indices.cpp" ) diff --git a/Point_set_processing_3/include/CGAL/estimate_scale.h b/Point_set_processing_3/include/CGAL/estimate_scale.h index 41ee3dcc07f..6243bfc4307 100644 --- a/Point_set_processing_3/include/CGAL/estimate_scale.h +++ b/Point_set_processing_3/include/CGAL/estimate_scale.h @@ -71,7 +71,7 @@ class Quick_multiscale_approximate_knn_distance - struct Pmap_unary_function : public CGAL::unary_function + struct Pmap_unary_function : public CGAL::cpp98::unary_function { PointMap point_map; Pmap_unary_function (PointMap point_map) : point_map (point_map) { } @@ -236,7 +236,7 @@ class Quick_multiscale_approximate_knn_distance - struct Pmap_unary_function : public CGAL::unary_function + struct Pmap_unary_function : public CGAL::cpp98::unary_function { PointMap point_map; Pmap_unary_function (PointMap point_map) : point_map (point_map) { } diff --git a/Point_set_processing_3/include/CGAL/mst_orient_normals.h b/Point_set_processing_3/include/CGAL/mst_orient_normals.h index b46e626e91f..f441f209de9 100644 --- a/Point_set_processing_3/include/CGAL/mst_orient_normals.h +++ b/Point_set_processing_3/include/CGAL/mst_orient_normals.h @@ -501,11 +501,12 @@ create_mst_graph( /** \ingroup PkgPointSetProcessingAlgorithms Orients the normals of the range of `points` using the propagation - of a seed orientation through a minimum spanning tree of the Riemannian graph [Hoppe92]. - + of a seed orientation through a minimum spanning tree of the Riemannian graph. This method modifies the order of input points so as to pack all sucessfully oriented points first, and returns an iterator over the first point with an unoriented normal (see erase-remove idiom). For this reason it should not be called on sorted containers. + It is based on \cgalCite{cgal:hddms-srup-92}. + \warning This function may fail when Boost version 1.54 is used, because of the following bug: https://svn.boost.org/trac/boost/ticket/9012 diff --git a/Point_set_processing_3/include/CGAL/structure_point_set.h b/Point_set_processing_3/include/CGAL/structure_point_set.h index 241bde88ec0..3721e82f110 100644 --- a/Point_set_processing_3/include/CGAL/structure_point_set.h +++ b/Point_set_processing_3/include/CGAL/structure_point_set.h @@ -36,7 +36,6 @@ #include #include -#include #include #include diff --git a/Point_set_processing_3/test/Point_set_processing_3/deprecated_analysis_test.cpp b/Point_set_processing_3/test/Point_set_processing_3/deprecated_analysis_test.cpp index e51b638500e..8ca967a03c3 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/deprecated_analysis_test.cpp +++ b/Point_set_processing_3/test/Point_set_processing_3/deprecated_analysis_test.cpp @@ -1,4 +1,4 @@ -#define CGAL_NO_DEPRECATION_WARNINGS +#include // analysis_test.cpp diff --git a/Point_set_processing_3/test/Point_set_processing_3/deprecated_bilateral_smoothing_test.cpp b/Point_set_processing_3/test/Point_set_processing_3/deprecated_bilateral_smoothing_test.cpp index dfc543b23cb..02b08a7ce30 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/deprecated_bilateral_smoothing_test.cpp +++ b/Point_set_processing_3/test/Point_set_processing_3/deprecated_bilateral_smoothing_test.cpp @@ -1,4 +1,4 @@ -#define CGAL_NO_DEPRECATION_WARNINGS +#include // bilateral_smoothing_test.cpp diff --git a/Point_set_processing_3/test/Point_set_processing_3/deprecated_edge_aware_upsample_test.cpp b/Point_set_processing_3/test/Point_set_processing_3/deprecated_edge_aware_upsample_test.cpp index b224b9e492e..e72f8e663be 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/deprecated_edge_aware_upsample_test.cpp +++ b/Point_set_processing_3/test/Point_set_processing_3/deprecated_edge_aware_upsample_test.cpp @@ -1,4 +1,4 @@ -#define CGAL_NO_DEPRECATION_WARNINGS +#include // edge_aware_upsample_test.cpp diff --git a/Point_set_processing_3/test/Point_set_processing_3/deprecated_hierarchy_simplification_test.cpp b/Point_set_processing_3/test/Point_set_processing_3/deprecated_hierarchy_simplification_test.cpp index ccbd09a79d9..009f01082f6 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/deprecated_hierarchy_simplification_test.cpp +++ b/Point_set_processing_3/test/Point_set_processing_3/deprecated_hierarchy_simplification_test.cpp @@ -1,4 +1,4 @@ -#define CGAL_NO_DEPRECATION_WARNINGS +#include #include diff --git a/Point_set_processing_3/test/Point_set_processing_3/deprecated_jet_pointer_as_property_map.cpp b/Point_set_processing_3/test/Point_set_processing_3/deprecated_jet_pointer_as_property_map.cpp index c1beace16e9..3e97a2c0c12 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/deprecated_jet_pointer_as_property_map.cpp +++ b/Point_set_processing_3/test/Point_set_processing_3/deprecated_jet_pointer_as_property_map.cpp @@ -1,4 +1,4 @@ -#define CGAL_NO_DEPRECATION_WARNINGS +#include #include diff --git a/Point_set_processing_3/test/Point_set_processing_3/deprecated_normal_estimation_test.cpp b/Point_set_processing_3/test/Point_set_processing_3/deprecated_normal_estimation_test.cpp index e3599957445..1ac14a5392f 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/deprecated_normal_estimation_test.cpp +++ b/Point_set_processing_3/test/Point_set_processing_3/deprecated_normal_estimation_test.cpp @@ -1,4 +1,4 @@ -#define CGAL_NO_DEPRECATION_WARNINGS +#include // normal_estimation_test.cpp diff --git a/Point_set_processing_3/test/Point_set_processing_3/deprecated_read_test.cpp b/Point_set_processing_3/test/Point_set_processing_3/deprecated_read_test.cpp index ee066eda0df..1f1b1ae4da0 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/deprecated_read_test.cpp +++ b/Point_set_processing_3/test/Point_set_processing_3/deprecated_read_test.cpp @@ -1,4 +1,4 @@ -#define CGAL_NO_DEPRECATION_WARNINGS +#include #include #include diff --git a/Point_set_processing_3/test/Point_set_processing_3/deprecated_read_test_with_different_pmaps.cpp b/Point_set_processing_3/test/Point_set_processing_3/deprecated_read_test_with_different_pmaps.cpp index 663b5934279..f15357b13da 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/deprecated_read_test_with_different_pmaps.cpp +++ b/Point_set_processing_3/test/Point_set_processing_3/deprecated_read_test_with_different_pmaps.cpp @@ -1,4 +1,4 @@ -#define CGAL_NO_DEPRECATION_WARNINGS +#include #include #include diff --git a/Point_set_processing_3/test/Point_set_processing_3/deprecated_remove_outliers_test.cpp b/Point_set_processing_3/test/Point_set_processing_3/deprecated_remove_outliers_test.cpp index d28a77f836e..0a473a22a57 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/deprecated_remove_outliers_test.cpp +++ b/Point_set_processing_3/test/Point_set_processing_3/deprecated_remove_outliers_test.cpp @@ -1,4 +1,4 @@ -#define CGAL_NO_DEPRECATION_WARNINGS +#include // remove_outliers_test.cpp diff --git a/Point_set_processing_3/test/Point_set_processing_3/deprecated_smoothing_test.cpp b/Point_set_processing_3/test/Point_set_processing_3/deprecated_smoothing_test.cpp index e3af0b0e11f..99e1356f9ca 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/deprecated_smoothing_test.cpp +++ b/Point_set_processing_3/test/Point_set_processing_3/deprecated_smoothing_test.cpp @@ -1,4 +1,4 @@ -#define CGAL_NO_DEPRECATION_WARNINGS +#include // smoothing_test.cpp diff --git a/Point_set_processing_3/test/Point_set_processing_3/deprecated_structuring_test.cpp b/Point_set_processing_3/test/Point_set_processing_3/deprecated_structuring_test.cpp index 0d084ad036a..ccbbebcbdb7 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/deprecated_structuring_test.cpp +++ b/Point_set_processing_3/test/Point_set_processing_3/deprecated_structuring_test.cpp @@ -1,4 +1,4 @@ -#define CGAL_NO_DEPRECATION_WARNINGS +#include #include #include diff --git a/Point_set_processing_3/test/Point_set_processing_3/deprecated_vcm_all_test.cpp b/Point_set_processing_3/test/Point_set_processing_3/deprecated_vcm_all_test.cpp index d68ba520908..55f707e0c98 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/deprecated_vcm_all_test.cpp +++ b/Point_set_processing_3/test/Point_set_processing_3/deprecated_vcm_all_test.cpp @@ -1,4 +1,4 @@ -#define CGAL_NO_DEPRECATION_WARNINGS +#include #include #include diff --git a/Point_set_processing_3/test/Point_set_processing_3/deprecated_vcm_plane_test.cpp b/Point_set_processing_3/test/Point_set_processing_3/deprecated_vcm_plane_test.cpp index baba0d5aa52..6093923c36c 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/deprecated_vcm_plane_test.cpp +++ b/Point_set_processing_3/test/Point_set_processing_3/deprecated_vcm_plane_test.cpp @@ -1,4 +1,4 @@ -#define CGAL_NO_DEPRECATION_WARNINGS +#include #include #include diff --git a/Point_set_processing_3/test/Point_set_processing_3/deprecated_wlop_simplify_and_regularize_test.cpp b/Point_set_processing_3/test/Point_set_processing_3/deprecated_wlop_simplify_and_regularize_test.cpp index 5110033f166..eb7467d422d 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/deprecated_wlop_simplify_and_regularize_test.cpp +++ b/Point_set_processing_3/test/Point_set_processing_3/deprecated_wlop_simplify_and_regularize_test.cpp @@ -1,4 +1,4 @@ -#define CGAL_NO_DEPRECATION_WARNINGS +#include // wlop_simplify_and_regularize_test.cpp diff --git a/Point_set_shape_detection_3/include/CGAL/Shape_detection_3/Efficient_RANSAC_traits.h b/Point_set_shape_detection_3/include/CGAL/Shape_detection_3/Efficient_RANSAC_traits.h index 2deb64aa6d9..dc2e8bddaea 100644 --- a/Point_set_shape_detection_3/include/CGAL/Shape_detection_3/Efficient_RANSAC_traits.h +++ b/Point_set_shape_detection_3/include/CGAL/Shape_detection_3/Efficient_RANSAC_traits.h @@ -25,6 +25,12 @@ #include +#define CGAL_DEPRECATED_HEADER "" +#define CGAL_REPLACEMENT_HEADER "" +#define CGAL_DEPRECATED_MESSAGE_DETAILS \ + "CGAL::Shape_detection_3::Efficient_RANSAC_traits<> has been replaced by the class "\ + "CGAL::Shape_detection_3::Shape_detection_traits<>." +#include #include @@ -51,9 +57,7 @@ namespace CGAL { class InputRange, class InputPointMap, class InputNormalMap> - struct - CGAL_DEPRECATED_MSG("CGAL::Shape_detection_3::Efficient_RANSAC_traits<> is now called CGAL::Shape_detection_3::Shape_detection_traits<>, please update your code") - Efficient_RANSAC_traits { + struct Efficient_RANSAC_traits { /// typedef typename Gt::FT FT; /// diff --git a/Point_set_shape_detection_3/test/Point_set_shape_detection_3/deprecated_test_scene.cpp b/Point_set_shape_detection_3/test/Point_set_shape_detection_3/deprecated_test_scene.cpp index 0a60f05e744..5f6425b0af5 100644 --- a/Point_set_shape_detection_3/test/Point_set_shape_detection_3/deprecated_test_scene.cpp +++ b/Point_set_shape_detection_3/test/Point_set_shape_detection_3/deprecated_test_scene.cpp @@ -1,4 +1,4 @@ -#define CGAL_NO_DEPRECATION_WARNINGS +#include #include "generators.h" diff --git a/Poisson_surface_reconstruction_3/examples/Poisson_surface_reconstruction_3/poisson_reconstruction_example.cpp b/Poisson_surface_reconstruction_3/examples/Poisson_surface_reconstruction_3/poisson_reconstruction_example.cpp index e45b6ea9ee0..31f49252ad2 100644 --- a/Poisson_surface_reconstruction_3/examples/Poisson_surface_reconstruction_3/poisson_reconstruction_example.cpp +++ b/Poisson_surface_reconstruction_3/examples/Poisson_surface_reconstruction_3/poisson_reconstruction_example.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include #include diff --git a/Poisson_surface_reconstruction_3/examples/Poisson_surface_reconstruction_3/poisson_reconstruction_function.cpp b/Poisson_surface_reconstruction_3/examples/Poisson_surface_reconstruction_3/poisson_reconstruction_function.cpp index 704c88bb495..8ddef0b3273 100644 --- a/Poisson_surface_reconstruction_3/examples/Poisson_surface_reconstruction_3/poisson_reconstruction_function.cpp +++ b/Poisson_surface_reconstruction_3/examples/Poisson_surface_reconstruction_3/poisson_reconstruction_function.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include diff --git a/Poisson_surface_reconstruction_3/include/CGAL/Mesh_3/Poisson_refine_cells_3.h b/Poisson_surface_reconstruction_3/include/CGAL/Mesh_3/Poisson_refine_cells_3.h index 6b5305564ed..936563a780e 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/Mesh_3/Poisson_refine_cells_3.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/Mesh_3/Poisson_refine_cells_3.h @@ -281,7 +281,7 @@ template class Poisson_refine_tets : public BaseP, - public Mesher_level < + public CGAL::Mesher_level < // qualified with CGAL:: as CGAL::Mesh_3::Mesher_level also exists Tr, Poisson_refine_tets, typename Tr::Cell_handle, @@ -294,7 +294,7 @@ class Poisson_refine_tets : Facets_level& facets_level; public: typedef Poisson_refine_tets Self; - typedef Mesher_level < + typedef CGAL::Mesher_level < Tr, Poisson_refine_tets, typename Tr::Cell_handle, diff --git a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_implicit_surface_3.h b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_implicit_surface_3.h index 1f80ca6a305..bfe7eb27711 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_implicit_surface_3.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_implicit_surface_3.h @@ -129,7 +129,7 @@ namespace CGAL { // non documented class template - class Poisson_implicit_function_wrapper : public CGAL::unary_function + class Poisson_implicit_function_wrapper : public CGAL::cpp98::unary_function { typedef FT (*Poisson_implicit_function)(FT, FT, FT); diff --git a/Poisson_surface_reconstruction_3/include/CGAL/Surface_mesher/Poisson_implicit_surface_oracle_3.h b/Poisson_surface_reconstruction_3/include/CGAL/Surface_mesher/Poisson_implicit_surface_oracle_3.h index 36c229aad36..d212d17c4fe 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/Surface_mesher/Poisson_implicit_surface_oracle_3.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/Surface_mesher/Poisson_implicit_surface_oracle_3.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -52,12 +53,6 @@ // compute the value of the potential in any point of space namespace CGAL { -#ifdef BOOST_MPL_CFG_NO_HAS_XXX -# error "BOOST_MPL_HAS_XXX_TRAIT_DEF is needed!" -#else - BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_set_on_surface, Set_on_surface_tag, true) -#endif - namespace Surface_mesher { /** @@ -100,19 +95,7 @@ namespace CGAL { ) */ - namespace { - - template - struct Return_min : CGAL::binary_function - { - T operator()(const T& a, const T& b) const - { - return (std::min)(a, b); - } - }; - - } // end anonymous namespace - + template < class GT, class Surface, diff --git a/Polygon_mesh_processing/benchmark/Polygon_mesh_processing/polygon_mesh_slicer.cpp b/Polygon_mesh_processing/benchmark/Polygon_mesh_processing/polygon_mesh_slicer.cpp index 092f2bec741..95f85c4f520 100644 --- a/Polygon_mesh_processing/benchmark/Polygon_mesh_processing/polygon_mesh_slicer.cpp +++ b/Polygon_mesh_processing/benchmark/Polygon_mesh_processing/polygon_mesh_slicer.cpp @@ -44,7 +44,7 @@ typedef CGAL::Timer Timer; template class Point_projector - : public CGAL::unary_function::vertex_descriptor, + : public CGAL::cpp98::unary_function::vertex_descriptor, typename boost::property_traits::type>::value_type> { typedef typename boost::property_map::type Ppmap; public: diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt index d9b8e95c9ac..22101de1caf 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/NamedParameters.txt @@ -6,9 +6,9 @@ In this package, all functions optional parameters are implemented as BGL option named parameters (see \ref BGLNamedParameters for more information on how to use them). Since the parameters of the various polygon mesh processing functions defined in this package are redundant, their long descriptions are centralized below. -The sequence of named parameters should start with `CGAL::parameters::`. +The sequence of named parameters starts with `CGAL::parameters::`. `CGAL::parameters::all_default()` can be used to indicate -that default values of optional named parameters must be used. +that default values of optional named parameters shall be used. In the following, we assume that the following types are provided as template parameters of polygon mesh processing functions and classes. Note that, for some of these functions, @@ -45,7 +45,7 @@ is the property map containing the index of each face of the input polygon mesh. `boost::graph_traits::%face_descriptor` as key type and the value type: \code typename boost::property_traits::type>::value_type \endcode Default: \code boost::get(CGAL::face_index, pmesh)\endcode -If this internal property map exists, its values should be initialized. +If this internal property map exists, its values must be initialized. \cgalNPEnd \cgalNPBegin{edge_is_constrained_map} \anchor PMP_edge_is_constrained_map @@ -54,7 +54,7 @@ being marked or not. In `isotropic_remeshing()` and `connected_components()`, the marked edges are constrained.\n Type: a class model of `ReadWritePropertyMap` with `boost::graph_traits::%edge_descriptor` as key type and -`bool` as value type. It should be default constructible.\n +`bool` as value type. It must be default constructible.\n Default: a default property map where no edge is constrained \cgalNPEnd \cgalNPTableEnd @@ -63,7 +63,7 @@ In addition to these named parameters, this package offers the following named p \cgalNPTableBegin \cgalNPBegin{geom_traits} \anchor PMP_geom_traits -is the geometric traits instance in which the mesh processing operation should be performed.\n +is the geometric traits instance used for the mesh processing operation.\n Type: a Geometric traits class.\n Default: \code typename CGAL::Kernel_traits< @@ -85,7 +85,7 @@ inserted several times.\n is the property map containing the number of feature edges being incident to the vertices of the polygon mesh `pmesh`.\n Type: a class model of `ReadWritePropertyMap` with `boost::graph_traits::%vertex_descriptor` as key type and -`int` as value type. It should be default constructible.\n +`int` as value type. It must be default constructible.\n Default: \code boost::get(CGAL::vertex_feature_degree_t(), pmesh) \endcode \cgalNPEnd @@ -95,7 +95,7 @@ Constrained vertices may be replaced by new vertices, but the number and locatio of vertices remain unchanged.\n Type: a class model of `ReadWritePropertyMap` with `boost::graph_traits::%vertex_descriptor` as key type and -`bool` as value type. It should be default constructible.\n +`bool` as value type. It must be default constructible.\n Default: a default property map where no vertex is constrained is provided. \cgalNPEnd @@ -159,6 +159,15 @@ during the remeshing process.\n Default: `false` \cgalNPEnd +\cgalNPBegin{collapse_constraints} \anchor PMP_collapse_constraints +enables the collapse of constraints listed by \ref PMP_edge_is_constrained_map +"edge_is_constrained_map" and boundary edges +in `isotropic_remeshing()`. If `false`, constraint edges cannot be collapsed +during the remeshing process.\n +Type: `bool` \n +Default: `true` +\cgalNPEnd + \cgalNPBegin{relax_constraints} \anchor PMP_relax_constraints enables the tangential relaxation step in `isotropic_remeshing()` to be performed on vertices that are endpoints of constraints listed @@ -188,21 +197,21 @@ enables the use of the Delaunay triangulation facet search space for hole fillin \cgalNPEnd \cgalNPBegin{use_random_uniform_sampling} \anchor PMP_use_random_uniform_sampling -is a parameter used in `sample_triangle_mesh()` to indicate if points should be picked +is a parameter used in `sample_triangle_mesh()` to indicate that the points are picked in a random uniform way.\n Type: `bool` \n Default: `true` \cgalNPEnd \cgalNPBegin{use_grid_sampling} \anchor PMP_use_grid_sampling -is a parameter used in `sample_triangle_mesh()` to indicate if points should be picked -in on a grid in each face.\n +is a parameter used in `sample_triangle_mesh()` to indicate that the points are picked +on a grid in each face.\n Type: `bool` \n Default: `false` \cgalNPEnd \cgalNPBegin{use_monte_carlo_sampling} \anchor PMP_use_monte_carlo_sampling -is a parameter used in `sample_triangle_mesh()` to indicate if points should be picked +is a parameter used in `sample_triangle_mesh()` to indicate that the points are picked using a Monte-Carlo approach.\n Type: `bool` \n Default: `false` @@ -210,21 +219,21 @@ using a Monte-Carlo approach.\n \cgalNPBegin{sample_edges} \anchor PMP_sample_edges is a parameter used in `sample_triangle_mesh()` to indicate if a dedicated sampling -of edges should be done.\n +of edges is done.\n Type: `bool` \n Default: `true` \cgalNPEnd \cgalNPBegin{sample_vertices} \anchor PMP_sample_vertices -is a parameter used in `sample_triangle_mesh()` to indicate if triangle vertices should -be copied in the output iterator.\n +is a parameter used in `sample_triangle_mesh()` to indicate that triangle vertices are +copied in the output iterator.\n Type: `bool` \n Default: `true` \cgalNPEnd \cgalNPBegin{sample_faces} \anchor PMP_sample_faces is a parameter used in `sample_triangle_mesh()` to indicate if the interior of faces -should be considered for the sampling.\n +is considered for the sampling.\n Type: `bool` \n Default: `true` \cgalNPEnd @@ -281,7 +290,7 @@ Monte-Carlo methods.\n \cgalNPEnd \cgalNPBegin{do_project} \anchor PMP_do_project -is a parameter used in `random_perturbation()` to set whether vertices should be re-projected +is a parameter used in `random_perturbation()` to set whether vertices are re-projected to the input surface after their geometric perturbation.\n Type: `bool` \n Default: `true` @@ -299,15 +308,22 @@ If this parameter is not provided, the perturbation is not deterministic \cgalNPBegin{outward_orientation} \anchor PMP_outward_orientation Parameter used in orientation functions to choose between an outward or inward orientation. \n -\b Type : `bool` \n -\b Default value is `true` +Type: `bool` \n +Default: `true` \cgalNPBegin{do_overlap_test_of_bounded_sides} \anchor PMP_do_overlap_test_of_bounded_sides Parameter used in intersection test functions to indicate whether overlapping tests of bounded sides -of close meshes should be done in addition to surface intersection tests. +of close meshes are done in addition to surface intersection tests. \n -\b Type : `bool` \n -\b Default value is `false` +Type: `bool` \n +Default: `false` +\cgalNPEnd + +\cgalNPBegin{projection_functor} \anchor PMP_projection_functor +Parameter used in `isotropic_remeshing()` to specify an alternative vertex projection method. +\n +Type: Unary function object with vertex descriptor as argument type. \n +Default: A function object projecting vertices on the input surface. \cgalNPEnd \cgalNPTableEnd diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt index d1e269af0ed..80e65018910 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/PackageDescription.txt @@ -176,6 +176,7 @@ and provides a list of the parameters that are used in this package. - `CGAL::Polygon_mesh_processing::edge_bbox()` - `CGAL::Polygon_mesh_processing::face_bbox()` - `CGAL::Polygon_mesh_processing::border_halfedges()` +- `CGAL::Polygon_mesh_processing::transform()` \todo add `clip_triangle_mesh()` using the code of `Polyhedron_place_clipping.h` and `PMP::corefine()` \todo fix and restore remove_degenerate_faces in the user and the reference manual diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt index de632eeadf7..6482ee54e73 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/Polygon_mesh_processing.txt @@ -571,11 +571,11 @@ and store them in property maps provided by the class `Surface_mesh`. \cgalExample{Polygon_mesh_processing/compute_normals_example.cpp} -\subsubsection NormalsExampleP Normals Computation for a Poyhedron_3 +\subsubsection NormalsExampleP Normals Computation for a Polyhedron_3 The following example illustrates how to compute the normals to faces and vertices -and store them in ordered or unordered maps as the class `Polyhedron` does +and store them in ordered or unordered maps as the class `Polyhedron_3` does not provide storage for the normals. \cgalExample{Polygon_mesh_processing/compute_normals_example_Polyhedron.cpp} diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/dependencies b/Polygon_mesh_processing/doc/Polygon_mesh_processing/dependencies index 52428e7009d..e9a5e6baf02 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/dependencies +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/dependencies @@ -12,3 +12,5 @@ Surface_mesh_deformation AABB_tree Triangulation_2 Spatial_sorting +Generator + diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/bbox.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/bbox.h index 033364bac9b..0c73a8655dd 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/bbox.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/bbox.h @@ -51,7 +51,7 @@ namespace CGAL { * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, * providing the functor `Construct_bbox_3` and the function * `Construct_bbox_3 construct_bbox_3_object()`. `Construct_bbox_3` @@ -101,7 +101,7 @@ namespace CGAL { * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, * providing the functor `Construct_bbox_3` and the function * `Construct_bbox_3 construct_bbox_3_object()`. `Construct_bbox_3` @@ -144,7 +144,7 @@ namespace CGAL { * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, * providing the functor `Construct_bbox_3` and the function * `Construct_bbox_3 construct_bbox_3_object()`. `Construct_bbox_3` @@ -188,7 +188,7 @@ namespace CGAL { * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, * providing the functor `Construct_bbox_3` and the function * `Construct_bbox_3 construct_bbox_3_object()`. `Construct_bbox_3` diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/border.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/border.h index 43dc3381ecd..6c30cb6d077 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/border.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/border.h @@ -155,7 +155,7 @@ namespace Polygon_mesh_processing { * @tparam PolygonMesh model of `HalfedgeGraph`. If `PolygonMesh` * has an internal property map * for `CGAL::face_index_t` and no `face_index_map` is given - * as a named parameter, then the internal one should be initialized + * as a named parameter, then the internal one must be initialized * @tparam FaceRange range of `boost::graph_traits::%face_descriptor`, model of `Range`. Its iterator type is `InputIterator`. diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/compute_normal.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/compute_normal.h index 900e8abd7d6..3fc5faadc0f 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/compute_normal.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/compute_normal.h @@ -109,7 +109,7 @@ void sum_normals(const PM& pmesh, * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for -* `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd +* `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * @@ -168,7 +168,7 @@ compute_face_normal(typename boost::graph_traits::face_descriptor f * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for -* `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd +* `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * @@ -205,7 +205,7 @@ compute_face_normals(const PolygonMesh& pmesh * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for -* `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd +* `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * @@ -285,7 +285,7 @@ compute_vertex_normal(typename boost::graph_traits::vertex_descript * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for -* `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd +* `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * @@ -331,7 +331,7 @@ compute_vertex_normals(const PolygonMesh& pmesh * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for -* `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd +* `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/connected_components.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/connected_components.h index b08cea61b7e..c72b3d54d98 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/connected_components.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/connected_components.h @@ -183,7 +183,7 @@ connected_component(typename boost::graph_traits::face_descriptor s * \ingroup keep_connected_components_grp * computes for each face the index of the corresponding connected component. * - * A property map for `CGAL::face_index_t` should be either available as an internal property map + * A property map for `CGAL::face_index_t` must be either available as an internal property map * to `pmesh` or provided as one of the \ref pmp_namedparameters "Named Parameters". * * \tparam PolygonMesh a model of `FaceListGraph` @@ -269,7 +269,7 @@ void keep_connected_components(PolygonMesh& pmesh * Keep `nb_components_to_keep` largest connected components. * * Property maps for `CGAL::face_index_t` and `CGAL::vertex_index_t` - * should be either available as internal property maps + * must be either available as internal property maps * to `pmesh` or provided as \ref pmp_namedparameters "Named Parameters". * * \tparam PolygonMesh a model of `FaceListGraph` and `MutableFaceGraph` @@ -352,7 +352,7 @@ std::size_t keep_largest_connected_components(PolygonMesh& pmesh, * removes connected components with less than a given number of faces. * * Property maps for `CGAL::face_index_t` and `CGAL::vertex_index_t` - * should be either available as internal property maps + * must be either available as internal property maps * to `pmesh` or provided as \ref pmp_namedparameters "Named Parameters". * * \tparam PolygonMesh a model of `FaceListGraph` and `MutableFaceGraph` @@ -567,7 +567,7 @@ void keep_or_remove_connected_components(PolygonMesh& pmesh * then the behavior of this function is undefined. * * Property maps for `CGAL::vertex_index_t` -* should be either available as internal property map +* must be either available as internal property map * to `pmesh` or provided as \ref pmp_namedparameters "Named Parameters". * * \tparam PolygonMesh a model of `FaceListGraph` and `MutableFaceGraph` @@ -610,7 +610,7 @@ void keep_connected_components(PolygonMesh& pmesh * then the behavior of this function is undefined. * * Property maps for `CGAL::vertex_index_t` -* should be either available as internal property map +* must be either available as internal property map * to `pmesh` or provided as \ref pmp_namedparameters "Named Parameters". * * @@ -651,7 +651,7 @@ void remove_connected_components(PolygonMesh& pmesh * and removes the other connected components and all isolated vertices. * * Property maps for `CGAL::face_index_t` and `CGAL::vertex_index_t` -* should be either available as internal property maps +* must be either available as internal property maps * to `pmesh` or provided as \ref pmp_namedparameters "Named Parameters". * * \note If the removal of the connected components makes `pmesh` a non-manifold surface, @@ -709,7 +709,7 @@ void remove_connected_components(PolygonMesh& pmesh * and removes the other connected components and all isolated vertices. * * Property maps for `CGAL::face_index_t` and `CGAL::vertex_index_t` -* should be either available as internal property maps +* must be either available as internal property maps * to `pmesh` or provided as \ref pmp_namedparameters "Named Parameters". * * \note If the removal of the connected components makes `pmesh` a non-manifold surface, diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h index c6f4c83e0fd..b92329c24d4 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h @@ -144,7 +144,7 @@ bool recursive_does_bound_a_volume(const TriangleMesh& tm, * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh` + * `CGAL::vertex_point_t` must be available in `TriangleMesh` * \cgalParamEnd * \cgalParamBegin{face_index_map} * a property map containing the index of each face of `tm`. @@ -453,7 +453,7 @@ boolean_operation( TriangleMesh& tm1, * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm1` (`tm2`). * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh` + * `CGAL::vertex_point_t` must be available in `TriangleMesh` * \cgalParamEnd * \cgalParamBegin{edge_is_constrained_map} a property map containing the * constrained-or-not status of each edge of `tm1` (`tm2`). @@ -470,7 +470,7 @@ boolean_operation( TriangleMesh& tm1, * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm_out`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh` + * `CGAL::vertex_point_t` must be available in `TriangleMesh` * \cgalParamEnd * \cgalParamBegin{edge_is_constrained_map} a property map containing the * constrained-or-not status of each edge of `tm_out`. An edge of `tm_out` is constrained @@ -597,7 +597,7 @@ corefine_and_compute_difference( TriangleMesh& tm1, * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm1` (`tm2`). * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh` + * `CGAL::vertex_point_t` must be available in `TriangleMesh` * \cgalParamEnd * \cgalParamBegin{edge_is_constrained_map} a property map containing the * constrained-or-not status of each edge of `tm1` (`tm2`) @@ -690,7 +690,7 @@ namespace experimental { * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh` + * `CGAL::vertex_point_t` must be available in `TriangleMesh` * \cgalParamEnd * \cgalParamBegin{edge_is_constrained_map} a property map containing the * constrained-or-not status of each edge of `tm` @@ -756,7 +756,7 @@ namespace experimental { * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh` + * `CGAL::vertex_point_t` must be available in `TriangleMesh` * \cgalParamEnd * \cgalParamBegin{edge_is_constrained_map} a property map containing the * constrained-or-not status of each edge of `tm` diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/detect_features.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/detect_features.h index ea86140bca8..330e348277b 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/detect_features.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/detect_features.h @@ -252,7 +252,7 @@ template::%edge_descriptor` - * as key type and `bool` as value type. It should be default constructible. + * as key type and `bool` as value type. It must be default constructible. * \tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" * * \param pmesh the polygon mesh @@ -380,7 +380,7 @@ namespace internal * computing a * surface patch id for each face. * - * A property map for `CGAL::face_index_t`should be either available + * A property map for `CGAL::face_index_t` must be either available * as an internal property map to `pmesh` or provided as one of the Named Parameters. * * \tparam PolygonMesh a model of `FaceGraph` diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/distance.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/distance.h index 76fa27eb53d..cbde9dc433c 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/distance.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/distance.h @@ -244,7 +244,7 @@ sample_triangles(const FaceRange& triangles, * \cgalParamBegin{vertex_point_map} the property map with the points * associated to the vertices of `tm`. If this parameter is omitted, * an internal property map for `CGAL::vertex_point_t` - * should be available for `TriangleMesh`. + * must be available for `TriangleMesh`. * \cgalParamEnd * \cgalParamBegin{geom_traits} a model of `PMPDistanceTraits`. \cgalParamEnd * \cgalParamBegin{use_random_uniform_sampling} @@ -611,8 +611,8 @@ double approximate_Hausdorff_distance( * * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `tm2` - * If this parameter is omitted, an internal property map for CGAL::vertex_point_t should be available in `TriangleMesh` - * and in all places where vertex_point_map is used. + * If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` must be available in `TriangleMesh` + * and in all places where `vertex_point_map` is used. * \cgalParamEnd * \cgalNamedParamsEnd * The function `CGAL::parameters::all_default()` can be used to indicate to use the default values for @@ -671,7 +671,7 @@ double approximate_symmetric_Hausdorff_distance( * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm`. If this parameter is omitted, - * an internal property map for `CGAL::vertex_point_t` should be available for the + * an internal property map for `CGAL::vertex_point_t` must be available for the vertices of `tm` \cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPDistanceTraits`\cgalParamEnd * \cgalNamedParamsEnd @@ -708,7 +708,7 @@ double max_distance_to_triangle_mesh(const PointRange& points, * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm`. If this parameter is omitted, - * an internal property map for `CGAL::vertex_point_t` should be available for the + * an internal property map for `CGAL::vertex_point_t` must be available for the vertices of `tm` \cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPDistanceTraits`. \cgalParamEnd * \cgalNamedParamsEnd diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/fair.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/fair.h index e955324d22c..ecc2f3ebdad 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/fair.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/fair.h @@ -96,7 +96,7 @@ namespace internal { \cgalNamedParamsBegin \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `tmesh`. If this parameter is omitted, an internal property map for - `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd \cgalParamBegin{fairing_continuity} tangential continuity of the output surface patch. The larger `fairing_continuity` gets, the more fixed vertices are required \cgalParamEnd \cgalParamBegin{sparse_linear_solver} an instance of the sparse linear solver used for fairing \cgalParamEnd \cgalNamedParamsEnd diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h index c7876d0d4cb..5c72f1c5fbe 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h @@ -356,7 +356,7 @@ public: is_intersection(intersection_edges); std::size_t nb_patches = PMP::connected_components(tm, - bind_property_maps(fids,make_property_map(&patch_ids[0])), + bind_property_maps(fids,make_property_map(patch_ids)), params::edge_is_constrained_map( is_intersection) .face_index_map(fids)); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h index e5e71f80a5b..bfbe181b40e 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Isotropic_remeshing/remesh_impl.h @@ -105,7 +105,7 @@ namespace internal { friend void put(No_constraint_pmap& , const key_type& , const bool ) {} }; - template + template struct Border_constraint_pmap { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; @@ -125,6 +125,8 @@ namespace internal { : border_edges_ptr(new std::set() ) , pmesh_ptr_(NULL) {} + + template Border_constraint_pmap(const PM& pmesh , const FaceRange& faces , const FIMap& fimap) @@ -139,14 +141,14 @@ namespace internal { border_edges_ptr->insert(edge(h, *pmesh_ptr_)); } - friend bool get(const Border_constraint_pmap& map, + friend bool get(const Border_constraint_pmap& map, const edge_descriptor& e) { CGAL_assertion(map.pmesh_ptr_!=NULL); return map.border_edges_ptr->count(e)!=0; } - friend void put(Border_constraint_pmap& map, + friend void put(Border_constraint_pmap& map, const edge_descriptor& e, const bool is) { @@ -160,21 +162,33 @@ namespace internal { template struct Connected_components_pmap { typedef typename boost::graph_traits::face_descriptor face_descriptor; typedef std::size_t Patch_id; typedef FaceIndexMap FIMap; - typedef EdgeIsConstrainedMap ECMap; - typedef Connected_components_pmap CCMap; + typedef Connected_components_pmap CCMap; typedef CGAL::dynamic_face_property_t Face_property_tag; typedef typename boost::property_map::type Patch_ids_map; Patch_ids_map patch_ids_map; std::size_t nb_cc; + template + bool same_range(const Range& r1, const Range& r2) + { + return boost::begin(r1)==boost::begin(r2) && + boost::end(r1)==boost::end(r2); + } + + template + bool same_range(const Range1& r1, const Range2& r2) + { + return std::distance(boost::begin(r1), boost::end(r1)) == + std::distance(boost::begin(r2), boost::end(r2)); + } + public: typedef face_descriptor key_type; typedef Patch_id value_type; @@ -183,7 +197,9 @@ namespace internal { //note pmesh is a non-const ref because properties are added and removed //modify the mesh data structure, but not the mesh itself - Connected_components_pmap(PM& pmesh + template + Connected_components_pmap(const FaceRange& face_range + , PM& pmesh , EdgeIsConstrainedMap ecmap , FIMap fimap , const bool do_init = true) @@ -194,15 +210,29 @@ namespace internal { #ifdef CGAL_PMP_REMESHING_VERBOSE std::cout << "Compute connected components property map." << std::endl; #endif - nb_cc - = PMP::connected_components(pmesh, - patch_ids_map, - PMP::parameters::edge_is_constrained_map(ecmap) - .face_index_map(fimap)); - if(nb_cc == 1){ - patch_ids_map = Patch_ids_map(); + if ( same_range(face_range, (faces(pmesh))) ) + { + // applied on the whole mesh + nb_cc + = PMP::connected_components(pmesh, + patch_ids_map, + PMP::parameters::edge_is_constrained_map(ecmap) + .face_index_map(fimap)); + } + else + { + // applied on a subset of the mesh + nb_cc + = PMP::connected_components(pmesh, + patch_ids_map, + PMP::parameters::edge_is_constrained_map( + make_OR_property_map(ecmap + , internal::Border_constraint_pmap(pmesh, face_range, fimap) ) ) + .face_index_map(fimap)); } } + else + nb_cc=0; // default value } @@ -221,10 +251,12 @@ namespace internal { template + typename VertexPointMap, + typename FacePatchMap> bool constraints_are_short_enough(const PM& pmesh, EdgeConstraintMap ecmap, VertexPointMap vpmap, + const FacePatchMap& fpm, const double& high) { double sqh = high*high; @@ -232,9 +264,11 @@ namespace internal { typedef typename boost::graph_traits::edge_descriptor edge_descriptor; BOOST_FOREACH(edge_descriptor e, edges(pmesh)) { - if (get(ecmap, e)) + halfedge_descriptor h = halfedge(e, pmesh); + if ( is_border(e, pmesh) || + get(ecmap, e) || + get(fpm, face(h,pmesh))!=get(fpm, face(opposite(h,pmesh),pmesh)) ) { - halfedge_descriptor h = halfedge(e, pmesh); if (sqh < CGAL::squared_distance(get(vpmap, source(h, pmesh)), get(vpmap, target(h, pmesh)))) { @@ -311,9 +345,6 @@ namespace internal { { halfedge_status_pmap_ = get(CGAL::dynamic_halfedge_property_t(), pmesh); - BOOST_FOREACH(halfedge_descriptor h, halfedges(mesh_)) - put(halfedge_status_pmap_, h, MESH); - CGAL_assertion(CGAL::is_triangle_mesh(mesh_)); } @@ -331,8 +362,6 @@ namespace internal { { tag_halfedges_status(face_range); //called first - constrain_patch_corners(face_range); - BOOST_FOREACH(face_descriptor f, face_range) { if (is_degenerate_triangle_face(halfedge(f,mesh_),mesh_,vpmap_,GeomTraits())){ @@ -370,6 +399,7 @@ namespace internal { // split edges of edge_range that have their length > high + // Note: only used to split a range of edges provided as input template void split_long_edges(const EdgeRange& edge_range, const double& high) @@ -391,12 +421,7 @@ namespace internal { { double sqlen = sqlength(e); if (sqlen > sq_high) - { long_edges.insert(long_edge(halfedge(e, mesh_), sqlen)); - put(ecmap_, e, false); - } - else - put(ecmap_, e, true); } //split long edges @@ -412,6 +437,8 @@ namespace internal { //split edge Point refinement_point = this->midpoint(he); halfedge_descriptor hnew = CGAL::Euler::split_edge(he, mesh_); + // propagate the constrained status + put(ecmap_, edge(hnew, mesh_), get(ecmap_, edge(he, mesh_))); CGAL_assertion(he == next(hnew, mesh_)); ++nb_splits; @@ -430,23 +457,22 @@ namespace internal { long_edges.insert(long_edge(hnew, sqlen_new)); long_edges.insert(long_edge(next(hnew, mesh_), sqlen_new)); } - else - { - put(ecmap_, edge(hnew, mesh_), true); - put(ecmap_, edge(next(hnew, mesh_), mesh_), true); - } //insert new edges to keep triangular faces, and update long_edges if (!is_border(hnew, mesh_)) { - CGAL::Euler::split_face(hnew, next(next(hnew, mesh_), mesh_), mesh_); + halfedge_descriptor hnew2 = + CGAL::Euler::split_face(hnew, next(next(hnew, mesh_), mesh_), mesh_); + put(ecmap_, edge(hnew2, mesh_), false); } //do it again on the other side if we're not on boundary halfedge_descriptor hnew_opp = opposite(hnew, mesh_); if (!is_border(hnew_opp, mesh_)) { - CGAL::Euler::split_face(prev(hnew_opp, mesh_), next(hnew_opp, mesh_), mesh_); + halfedge_descriptor hnew2 = + CGAL::Euler::split_face(prev(hnew_opp, mesh_), next(hnew_opp, mesh_), mesh_); + put(ecmap_, edge(hnew2, mesh_), false); } } #ifdef CGAL_PMP_REMESHING_VERBOSE @@ -511,6 +537,7 @@ namespace internal { Point refinement_point = this->midpoint(he); halfedge_descriptor hnew = CGAL::Euler::split_edge(he, mesh_); CGAL_assertion(he == next(hnew, mesh_)); + put(ecmap_, edge(hnew, mesh_), get(ecmap_, edge(he, mesh_)) ); ++nb_splits; //move refinement point @@ -540,6 +567,7 @@ namespace internal { halfedge_descriptor hnew2 = CGAL::Euler::split_face(hnew, next(next(hnew, mesh_), mesh_), mesh_); + put(ecmap_, edge(hnew2, mesh_), false); Halfedge_status snew = (is_on_patch(hnew) || is_on_patch_border(hnew)) ? PATCH : MESH; @@ -562,6 +590,7 @@ namespace internal { halfedge_descriptor hnew2 = CGAL::Euler::split_face(prev(hnew_opp, mesh_), next(hnew_opp, mesh_), mesh_); + put(ecmap_, edge(hnew2, mesh_), false); Halfedge_status snew = (is_on_patch(hnew_opp) || is_on_patch_border(hnew_opp)) ? PATCH : MESH; @@ -597,7 +626,9 @@ namespace internal { // "collapses and thus removes all edges that are shorter than a // threshold `low`. [...] testing before each collapse whether the collapse // would produce an edge that is longer than `high`" - void collapse_short_edges(const double& low, const double& high) + void collapse_short_edges(const double& low, + const double& high, + const bool collapse_constraints) { typedef boost::bimap< boost::bimaps::set_of, @@ -619,7 +650,7 @@ namespace internal { BOOST_FOREACH(edge_descriptor e, edges(mesh_)) { double sqlen = sqlength(e); - if( (sqlen < sq_low) && is_collapse_allowed(e) ) + if ((sqlen < sq_low) && is_collapse_allowed(e, collapse_constraints)) short_edges.insert(short_edge(halfedge(e, mesh_), sqlen)); } #ifdef CGAL_PMP_REMESHING_VERBOSE_PROGRESS @@ -641,7 +672,7 @@ namespace internal { #endif edge_descriptor e = edge(he, mesh_); - if (!is_collapse_allowed(e)) + if (!is_collapse_allowed(e, collapse_constraints)) continue; //situation could have changed since it was added to the bimap //handle the boundary case : @@ -663,39 +694,38 @@ namespace internal { vertex_descriptor va = source(he, mesh_); vertex_descriptor vb = target(he, mesh_); - bool swap_done = false; - if (is_on_patch_border(va) && !is_on_patch_border(vb)) + bool is_va_constrained = is_constrained(va) || is_on_patch_border(va); + bool is_vb_constrained = is_constrained(vb) || is_on_patch_border(vb); + + + // do not collapse edge with two constrained vertices + if (is_va_constrained && is_vb_constrained) continue; + + bool can_swap = !is_vb_constrained; + if (is_va_constrained) { he = opposite(he, mesh_); - va = source(he, mesh_); - vb = target(he, mesh_); - swap_done = true; - CGAL_assertion(is_on_patch_border(vb) && !is_on_patch_border(va)); + e=edge(he, mesh_); + std::swap(va, vb); + can_swap=false; } if(!collapse_does_not_invert_face(he)) { - if (!swap_done//if swap has already been done, don't re-swap - && collapse_does_not_invert_face(opposite(he, mesh_))) + if (can_swap//if swap allowed (no constrained vertices) + && collapse_does_not_invert_face(opposite(he, mesh_))) { he = opposite(he, mesh_); - va = source(he, mesh_); - vb = target(he, mesh_); - - if (is_on_patch_border(va) && !is_on_patch_border(vb)) - continue;//we cannot swap again. It would lead to a face inversion - else if (is_corner(va) && !is_corner(vb)) - continue;//idem + e=edge(he, mesh_); + std::swap(va, vb); } else continue;//both directions invert a face } CGAL_assertion(collapse_does_not_invert_face(he)); - CGAL_assertion(is_collapse_allowed(e)); + CGAL_assertion(is_collapse_allowed(e, collapse_constraints)); - if (degree(va, mesh_) < 3 - || degree(vb, mesh_) < 3 - || !CGAL::Euler::does_satisfy_link_condition(e, mesh_))//necessary to collapse + if (!CGAL::Euler::does_satisfy_link_condition(e, mesh_))//necessary to collapse continue; //check that collapse would not create an edge with length > high @@ -710,9 +740,9 @@ namespace internal { break; } } - //before collapsing va into vb, check that it does not break a corner - //if it is allowed, perform the collapse - if (collapse_ok && !is_constrained(va) && !is_corner(va)) + // before collapsing va into vb, check that it does not break a corner + // or a constrained vertex + if (collapse_ok) { //"collapse va into vb along e" // remove edges incident to va and vb, because their lengths will change @@ -728,50 +758,36 @@ namespace internal { } //before collapse + halfedge_descriptor he_opp= opposite(he, mesh_); bool mesh_border_case = is_on_border(he); - bool mesh_border_case_opp = is_on_border(opposite(he, mesh_)); - halfedge_descriptor ep_p = prev(opposite(he, mesh_), mesh_); - halfedge_descriptor epo_p = opposite(ep_p, mesh_); + bool mesh_border_case_opp = is_on_border(he_opp); + halfedge_descriptor ep_p = prev(he_opp, mesh_); halfedge_descriptor en = next(he, mesh_); - halfedge_descriptor en_p = next(opposite(he, mesh_), mesh_); - Halfedge_status s_ep_p = status(ep_p); - Halfedge_status s_epo_p = status(epo_p); - Halfedge_status s_ep = status(prev(he, mesh_)); - Halfedge_status s_epo = status(opposite(prev(he, mesh_), mesh_)); + halfedge_descriptor ep = prev(he, mesh_); + halfedge_descriptor en_p = next(he_opp, mesh_); // merge halfedge_status to keep the more important on both sides //do it before collapse is performed to be sure everything is valid if (!mesh_border_case) - merge_status(en, s_epo, s_ep); + merge_and_update_status(en, ep); if (!mesh_border_case_opp) - merge_status(en_p, s_epo_p, s_ep_p); + merge_and_update_status(en_p, ep_p); - halfedge_and_opp_removed(he); - if (!mesh_border_case) - halfedge_and_opp_removed(prev(he, mesh_)); - if (!mesh_border_case_opp) - halfedge_and_opp_removed(prev(opposite(he, mesh_), mesh_)); - - //constrained case - bool constrained_case = is_constrained(va) || is_constrained(vb); - if (constrained_case) - { - CGAL_assertion(is_constrained(va) ^ is_constrained(vb));//XOR - set_constrained(va, false); - set_constrained(vb, false); - } + if (!protect_constraints_) + put(ecmap_, e, false); + else + CGAL_assertion( !get(ecmap_, e) ); //perform collapse - Point target_point = get(vpmap_, vb); - vertex_descriptor vkept = CGAL::Euler::collapse_edge(e, mesh_); - put(vpmap_, vkept, target_point); + CGAL_assertion(target(halfedge(e, mesh_), mesh_) == vb); + vertex_descriptor vkept = CGAL::Euler::collapse_edge(e, mesh_, ecmap_); + CGAL_assertion(is_valid(mesh_)); + CGAL_assertion(vkept == vb);//is the constrained point still here ++nb_collapses; //fix constrained case - if (constrained_case)//we have made sure that collapse goes to constrained vertex - set_constrained(vkept, true); - - fix_degenerate_faces(vkept, short_edges, sq_low); + CGAL_assertion((is_constrained(vkept) || is_on_patch_border(vb)) == (is_va_constrained || is_vb_constrained)); + fix_degenerate_faces(vkept, short_edges, sq_low, collapse_constraints); #ifdef CGAL_PMP_REMESHING_DEBUG debug_status_map(); @@ -782,7 +798,7 @@ namespace internal { BOOST_FOREACH(halfedge_descriptor ht, halfedges_around_target(vkept, mesh_)) { double sqlen = sqlength(ht); - if( (sqlen < sq_low) && is_collapse_allowed(edge(ht, mesh_)) ) + if ((sqlen < sq_low) && is_collapse_allowed(edge(ht, mesh_), collapse_constraints)) short_edges.insert(short_edge(ht, sqlen)); } }//end if(collapse_ok) @@ -842,6 +858,8 @@ namespace internal { Patch_id pid = get_patch_id(face(he, mesh_)); + CGAL_assertion( is_flip_topologically_allowed(edge(he, mesh_)) ); + CGAL_assertion( !get(ecmap_, edge(he, mesh_)) ); CGAL::Euler::flip_edge(he, mesh_); vva -= 1; vvb -= 1; @@ -879,6 +897,8 @@ namespace internal { || !check_normals(target(he, mesh_)) || !check_normals(source(he, mesh_))) { + CGAL_assertion( is_flip_topologically_allowed(edge(he, mesh_)) ); + CGAL_assertion( !get(ecmap_, edge(he, mesh_)) ); CGAL::Euler::flip_edge(he, mesh_); --nb_flips; @@ -944,10 +964,10 @@ namespace internal { else if (is_on_patch(v)) { - Vector_3 vn = PMP::compute_vertex_normal(v, mesh_ - , PMP::parameters::vertex_point_map(vpmap_) - .geom_traits(GeomTraits())); - put(propmap_normals, v, vn); + Vector_3 vn = PMP::compute_vertex_normal(v, mesh_ + , PMP::parameters::vertex_point_map(vpmap_) + .geom_traits(GeomTraits())); + put(propmap_normals, v, vn); Vector_3 move = CGAL::NULL_VECTOR; unsigned int star_size = 0; @@ -1021,7 +1041,7 @@ namespace internal { put(vpmap_, vp.first, initial_pos);//cancel move } - CGAL_assertion(is_valid(mesh_)); + CGAL_assertion(is_valid_polygon_mesh(mesh_)); CGAL_assertion(is_triangle_mesh(mesh_)); }//end for loop (nit == nb_iterations) @@ -1038,7 +1058,7 @@ namespace internal { // PMP book : // "maps the vertices back to the surface" - void project_to_surface() + void project_to_surface(boost::param_not_found) { //todo : handle the case of boundary vertices #ifdef CGAL_PMP_REMESHING_VERBOSE @@ -1055,6 +1075,35 @@ namespace internal { Point proj = trees[patch_id_to_index_map[get_patch_id(face(halfedge(v, mesh_), mesh_))]]->closest_point(get(vpmap_, v)); put(vpmap_, v, proj); } + CGAL_assertion(is_valid_polygon_mesh(mesh_)); + CGAL_assertion(is_triangle_mesh(mesh_)); +#ifdef CGAL_PMP_REMESHING_DEBUG + debug_self_intersections(); +#endif +#ifdef CGAL_PMP_REMESHING_VERBOSE + std::cout << "done." << std::endl; +#endif + +#ifdef CGAL_DUMP_REMESHING_STEPS + dump("5-project.off"); +#endif + } + + template + void project_to_surface(const ProjectionFunctor& proj) + { + //todo : handle the case of boundary vertices +#ifdef CGAL_PMP_REMESHING_VERBOSE + std::cout << "Project to surface..."; + std::cout.flush(); +#endif + BOOST_FOREACH(vertex_descriptor v, vertices(mesh_)) + { + if (is_constrained(v) || is_isolated(v) || !is_on_patch(v)) + continue; + //note if v is constrained, it has not moved + put(vpmap_, v, proj(v)); + } CGAL_assertion(is_valid(mesh_)); CGAL_assertion(is_triangle_mesh(mesh_)); #ifdef CGAL_PMP_REMESHING_DEBUG @@ -1206,7 +1255,8 @@ private: } } - bool is_collapse_allowed(const edge_descriptor& e) const + bool is_collapse_allowed(const edge_descriptor& e + , const bool collapse_constraints) const { halfedge_descriptor he = halfedge(e, mesh_); halfedge_descriptor hopp = opposite(he, mesh_); @@ -1214,7 +1264,7 @@ private: if (is_on_mesh(he) && is_on_mesh(hopp)) return false; - if (protect_constraints_ && is_constrained(e)) + if ( (protect_constraints_ || !collapse_constraints) && is_constrained(e)) return false; if (is_on_patch(he)) //hopp is also on patch { @@ -1278,10 +1328,23 @@ private: return true;//we already checked we're not pinching a hole in the patch } + bool is_flip_topologically_allowed(const edge_descriptor& e) const + { + halfedge_descriptor h=halfedge(e, mesh_); + return !halfedge(target(next(h, mesh_), mesh_), + target(next(opposite(h, mesh_), mesh_), mesh_), + mesh_).second; + } + bool is_flip_allowed(const edge_descriptor& e) const { - return is_flip_allowed(halfedge(e, mesh_)) - && is_flip_allowed(opposite(halfedge(e, mesh_), mesh_)); + bool flip_possible = is_flip_allowed(halfedge(e, mesh_)) + && is_flip_allowed(opposite(halfedge(e, mesh_), mesh_)); + + if (!flip_possible) return false; + + // the flip is not possible if the edge already exists + return is_flip_topologically_allowed(e); } bool is_flip_allowed(const halfedge_descriptor& h) const @@ -1369,10 +1432,6 @@ private: { return get(vcmap_, v); } - void set_constrained(const vertex_descriptor& v, const bool b) - { - put(vcmap_, v, b); - } bool is_isolated(const vertex_descriptor& v) const { return halfedges_around_target(v, mesh_).empty(); @@ -1415,48 +1474,12 @@ private: return PMP::compute_face_normal(f, mesh_, parameters::vertex_point_map(vpmap_)); } - template - void constrain_patch_corners(const FaceRange& face_range) - { - boost::container::flat_set visited; - - BOOST_FOREACH(face_descriptor f, face_range) - { - BOOST_FOREACH(halfedge_descriptor h, - halfedges_around_face(halfedge(f, mesh_), mesh_)) - { - vertex_descriptor vt = target(h, mesh_); - //treat target(h, mesh_) - if (visited.find(vt) != visited.end()) - continue;//already treated - - if (status(h) == PATCH)//h not on patch boundary - continue; //so neither is target(h, mesh_) - - //count incident MESH_BORDER edges - unsigned int nb_incident_borders = 0; - BOOST_FOREACH(halfedge_descriptor hv, - halfedges_around_target(h, mesh_)) - { - CGAL_assertion(vt == target(hv, mesh_)); - if ( (status(hv) == PATCH_BORDER && status(opposite(hv, mesh_)) == MESH_BORDER) - || (status(hv) == MESH_BORDER && status(opposite(hv, mesh_)) == PATCH_BORDER)) - nb_incident_borders++; - } - - if (nb_incident_borders == 1) //this is a special corner - set_constrained(vt, true); - - visited.insert(vt); - } - } - } - template void tag_halfedges_status(const FaceRange& face_range) { - //tag MESH, //h and hopp belong to the mesh, not the patch - //tag MESH_BORDER //h belongs to the mesh, face(hopp, pmesh) == null_face() + //init halfedges as: + // - MESH, //h and hopp belong to the mesh, not the patch + // - MESH_BORDER //h belongs to the mesh, face(hopp, pmesh) == null_face() BOOST_FOREACH(halfedge_descriptor h, halfedges(mesh_)) { //being part of the border of the mesh is predominant @@ -1478,35 +1501,41 @@ private: } } - internal::Border_constraint_pmap - border_map(mesh_, face_range, fimap_); - //override the border of PATCH - //tag PATCH_BORDER,//h belongs to the patch, hopp doesn't - BOOST_FOREACH(edge_descriptor e, edges(mesh_)) + // tag patch border halfedges + BOOST_FOREACH(halfedge_descriptor h, halfedges(mesh_)) { - if (get(ecmap_, e) - || get(border_map, e) - || get_patch_id(face(halfedge(e, mesh_), mesh_)) - != get_patch_id(face(opposite(halfedge(e, mesh_), mesh_), mesh_))) + if (status(h)==PATCH && status(opposite(h, mesh_))!=PATCH) { - //deal with h and hopp for borders that are sharp edges to be preserved - halfedge_descriptor h = halfedge(e, mesh_); - if (status(h) == PATCH){ - set_status(h, PATCH_BORDER); - has_border_ = true; - } + set_status(h, PATCH_BORDER); + has_border_ = true; + } + } - halfedge_descriptor hopp = opposite(h, mesh_); - if (status(hopp) == PATCH){ - set_status(hopp, PATCH_BORDER); - has_border_ = true; + // update status using constrained edge map + if (!boost::is_same >::value) + { + BOOST_FOREACH(edge_descriptor e, edges(mesh_)) + { + if (get(ecmap_, e)) + { + //deal with h and hopp for borders that are sharp edges to be preserved + halfedge_descriptor h = halfedge(e, mesh_); + if (status(h) == PATCH){ + set_status(h, PATCH_BORDER); + has_border_ = true; + } + + halfedge_descriptor hopp = opposite(h, mesh_); + if (status(hopp) == PATCH){ + set_status(hopp, PATCH_BORDER); + has_border_ = true; + } } } } } - - // for a Surface_mesh::Property_map we make MESH the default value Halfedge_status status(const halfedge_descriptor& h) const { return get(halfedge_status_pmap_,h); @@ -1518,17 +1547,16 @@ private: put(halfedge_status_pmap_,h,s); } - void merge_status(const halfedge_descriptor& en, - const Halfedge_status& s_epo, - const Halfedge_status& s_ep) + void merge_and_update_status(halfedge_descriptor en, + halfedge_descriptor ep) { - //get missing data + halfedge_descriptor eno = opposite(en, mesh_); + halfedge_descriptor epo = opposite(ep, mesh_); Halfedge_status s_eno = status(eno); + Halfedge_status s_epo = status(epo); - if (s_epo == MESH_BORDER && s_eno == MESH_BORDER) - return; - + Halfedge_status s_ep = status(ep); if(s_epo == MESH_BORDER || s_ep == MESH_BORDER || s_epo == PATCH_BORDER @@ -1537,13 +1565,26 @@ private: set_status(en, s_epo); set_status(eno, s_ep); } + else + { + Halfedge_status s_en = status(en); + if(s_eno == MESH_BORDER + || s_en == MESH_BORDER + || s_eno == PATCH_BORDER + || s_en == PATCH_BORDER) + { + set_status(ep, s_epo); + set_status(epo, s_ep); + } + } // else keep current status for en and eno } template void fix_degenerate_faces(const vertex_descriptor& v, Bimap& short_edges, - const double& sq_low) + const double& sq_low, + const bool collapse_constraints) { CGAL_assertion_code(std::size_t nb_done = 0); boost::unordered_set degenerate_faces; @@ -1587,7 +1628,8 @@ private: short_edges.left.erase(hf); short_edges.left.erase(hfo); - + CGAL_assertion( is_flip_topologically_allowed(edge(hf, mesh_)) ); + CGAL_assertion( !get(ecmap_, edge(hf, mesh_)) ); CGAL::Euler::flip_edge(hf, mesh_); CGAL_assertion_code(++nb_done); @@ -1604,7 +1646,7 @@ private: #endif //insert new edges in 'short_edges' - if (is_collapse_allowed(edge(hf, mesh_))) + if (is_collapse_allowed(edge(hf, mesh_), collapse_constraints)) { double sqlen = sqlength(hf); if (sqlen < sq_low) @@ -1747,12 +1789,6 @@ private: set_status(h, s); } - void halfedge_and_opp_removed(const halfedge_descriptor& h) - { - set_status(h,MESH); - set_status(opposite(h, mesh_),MESH); - } - std::size_t nb_valid_halfedges() const { return static_cast( @@ -1877,18 +1913,6 @@ private: return input_patch_ids_; } - void update_constraints_property_map() - { - BOOST_FOREACH(edge_descriptor e, edges(mesh_)) - { - if (is_on_patch_border(halfedge(e, mesh_)) - || is_on_patch_border(opposite(halfedge(e, mesh_), mesh_))) - put(ecmap_, e, true); - else - put(ecmap_, e, false); - } - } - private: PolygonMesh& mesh_; VertexPointMap& vpmap_; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h index 4a841e38e2c..16986c73b1b 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h @@ -383,7 +383,7 @@ struct Throw_at_first_output { * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd * \return `out` @@ -503,7 +503,7 @@ compute_face_face_intersection(const FaceRange& face_range1, * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `tm`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd * \return `out` @@ -627,7 +627,7 @@ compute_face_polyline_intersection( const FaceRange& face_range, * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `tm`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd * \return `out` @@ -934,7 +934,7 @@ compute_polylines_polylines_intersection(const PolylineRange& polylines1, * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd * \return `out` @@ -983,7 +983,7 @@ compute_face_face_intersection(const TriangleMesh& tm1, * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd * \return `out` @@ -1189,7 +1189,7 @@ bool do_intersect(const Polyline& polyline1, * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `tm1` (tm2`). * \attention The two property maps must have the same `value_type`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalParamBegin{do_overlap_test_of_bounded_sides} if set to `true` tests also the overlap of the bounded sides of `tm1` and `tm2`. * If `false` (default), only the intersection of surface triangles are tested. @@ -1273,7 +1273,7 @@ bool do_intersect(const TriangleMesh& tm1, * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `tm`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd * @@ -1329,7 +1329,7 @@ bool do_intersect(const TriangleMesh& tm, * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `tn`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd * @@ -1550,13 +1550,13 @@ struct Mesh_callback * \cgalParamEnd * \cgalNamedParamsEnd * \param nps an optional range of `vertex_point_map` named parameters containing the `VertexPointMap` of each mesh in `range`, in the same order. - * If this parameter is omitted, then an internal property map for `CGAL::vertex_point_t` should be available for every mesh in the range. + * If this parameter is omitted, then an internal property map for `CGAL::vertex_point_t` must be available for every mesh in the range. * All the vertex point maps must be of the same type. * * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of a mesh. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in the triangle mesh type used in the range + * `CGAL::vertex_point_t` must be available in the triangle mesh type used in the range * \cgalParamEnd * \cgalNamedParamsEnd */ diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/measure.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/measure.h index 358b5750667..e630333f6eb 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/measure.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/measure.h @@ -73,7 +73,7 @@ public: * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * @@ -154,7 +154,7 @@ public: * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * @@ -217,7 +217,7 @@ public: * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * @@ -293,7 +293,7 @@ public: * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * @@ -367,7 +367,7 @@ public: * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel` \cgalParamEnd * \cgalNamedParamsEnd * @@ -426,7 +426,7 @@ public: * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits}an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * @@ -479,7 +479,7 @@ public: * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `Kernel`\cgalParamEnd * \cgalNamedParamsEnd * diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h index 15d3299f895..7434a130cec 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -176,7 +176,7 @@ bool is_outward_oriented(const PolygonMesh& pmesh, const NamedParameters& np) { CGAL_warning(CGAL::is_closed(pmesh)); - CGAL_precondition(CGAL::is_valid(pmesh)); + CGAL_precondition(CGAL::is_valid_polygon_mesh(pmesh)); //check for empty pmesh CGAL_warning(faces(pmesh).first != faces(pmesh).second); @@ -456,7 +456,7 @@ void recursive_orient_volume_ccs( TriangleMesh& tm, * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm`. * If this parameter is omitted, an internal property map for -* `CGAL::vertex_point_t` should be available in `TriangleMesh` +* `CGAL::vertex_point_t` must be available in `TriangleMesh` * \cgalParamEnd * \cgalParamBegin{face_index_map} * a property map containing the index of each face of `tm`. @@ -480,7 +480,7 @@ void orient(TriangleMesh& tm, const NamedParameters& np) NamedParameters>::const_type Fid_map; CGAL_assertion(is_triangle_mesh(tm)); - CGAL_assertion(is_valid(tm)); + CGAL_assertion(is_valid_polygon_mesh(tm)); CGAL_assertion(is_closed(tm)); using boost::choose_param; @@ -561,7 +561,7 @@ void orient(TriangleMesh& tm) * \cgalParamBegin{vertex_point_map} * the property map with the points associated to the vertices of `tm`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh` + * `CGAL::vertex_point_t` must be available in `TriangleMesh` * \cgalParamEnd * \cgalParamBegin{face_index_map} * a property map containing the index of each face of `tm`. diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h index e1bfa72f14b..b8b6d1a5472 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h @@ -150,6 +150,9 @@ public: typedef typename boost::range_value< PolygonRange>::type Polygon; + if(boost::begin(polygons) == boost::end(polygons)){ + return true; + } //check there is no duplicated ordered edge, and //check there is no polygon with twice the same vertex std::set< std::pair > edge_set; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/random_perturbation.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/random_perturbation.h index d0fac0391c0..ea7362e1a95 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/random_perturbation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/random_perturbation.h @@ -135,7 +135,7 @@ namespace internal { * constrained-or-not status of each vertex of `tmesh`. A constrained vertex * cannot be modified at all during perturbation * \cgalParamEnd -* \cgalParamBegin{do_project} a boolean that sets whether vertices should be reprojected +* \cgalParamBegin{do_project} a boolean that sets whether vertices are reprojected * on the input surface after their coordinates random perturbation * \cgalParamEnd * \cgalParamBegin{random_seed} a non-negative integer value to seed the random diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine.h index a2be7b0ca52..8a6319284b5 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/refine.h @@ -57,7 +57,7 @@ namespace Polygon_mesh_processing { \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `tmesh` Instance of a class model of `ReadWritePropertyMap`. If this parameter is omitted, an internal property map for - `CGAL::vertex_point_t` should be available in `TriangleMesh` + `CGAL::vertex_point_t` must be available in `TriangleMesh` \cgalParamEnd \cgalParamBegin{density_control_factor} factor to control density of the output mesh, where larger values lead to denser refinements. diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h index 4a7dc4daead..d87cd651b6a 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/remesh.h @@ -63,7 +63,7 @@ namespace Polygon_mesh_processing { * If `0` is passed then only the edge-flip, tangential relaxation, and projection steps will be done. * @param np optional sequence of \ref pmp_namedparameters "Named Parameters" among the ones listed below * -* @pre if constraints protection is activated, the constrained edges should +* @pre if constraints protection is activated, the constrained edges must * not be longer than 4/3*`target_edge_length` * * \cgalNamedParamsBegin @@ -81,6 +81,7 @@ namespace Polygon_mesh_processing { * \cgalParamBegin{edge_is_constrained_map} a property map containing the * constrained-or-not status of each edge of `pmesh`. A constrained edge can be split * or collapsed, but not flipped, nor its endpoints moved by smoothing. +* Sub-edges generated by splitting are set to be constrained. * Note that patch boundary edges (i.e. incident to only one face in the range) * are always considered as constrained edges. * \cgalParamEnd @@ -96,6 +97,10 @@ namespace Polygon_mesh_processing { * good quality results. It can even fail to terminate because of cascading vertex * insertions. * \cgalParamEnd +* \cgalParamBegin{collapse_constraints} If `true`, the edges set as constrained +* in `edge_is_constrained_map` (or by default the boundary edges) +* are collapsed during remeshing. This value is ignored if `protect_constraints` is true; +* \cgalParamEnd * \cgalParamBegin{face_patch_map} a property map with the patch id's associated to the faces of `faces`. Instance of a class model of `ReadWritePropertyMap`. It gets updated during the remeshing process while new faces are created. @@ -107,11 +112,19 @@ namespace Polygon_mesh_processing { * constrained in `edge_is_constrained_map` and boundary edges move along the * constrained polylines they belong to. * \cgalParamEnd +* \cgalParamBegin{do_project} a boolean that sets whether vertices should be reprojected +* on the input surface after creation or displacement. +* \cgalParamEnd +* \cgalParamBegin{projection_functor} +* A function object used to project input vertices (moved by the smoothing) and created vertices. +* It must have `%Point_3 operator()(vertex_descriptor)`, `%Point_3` being the value type +* of the vertex point map. +* If not provided, vertices are projected on the input surface mesh. +* \cgalParamEnd * \cgalNamedParamsEnd * * @sa `split_long_edges()` * -*@todo add possibility to provide a functor that projects to a prescribed surface *@todo Deal with exact constructions Kernel. The only thing that makes sense is to * guarantee that the output vertices are exactly on the input surface. * To do so, we can do every construction in `double`, and use an exact process for @@ -134,6 +147,7 @@ void isotropic_remeshing(const FaceRange& faces typedef PolygonMesh PM; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::edge_descriptor edge_descriptor; using boost::get_param; using boost::choose_param; @@ -145,6 +159,9 @@ void isotropic_remeshing(const FaceRange& faces t.start(); #endif + static const bool need_aabb_tree = + boost::is_default_param(get_param(np, internal_np::projection_functor)); + typedef typename GetGeomTraits::type GT; typedef typename GetVertexPointMap::type VPMap; @@ -158,14 +175,10 @@ void isotropic_remeshing(const FaceRange& faces typedef typename boost::lookup_named_param_def < internal_np::edge_is_constrained_t, NamedParameters, - internal::Border_constraint_pmap//default + internal::No_constraint_pmap//default > ::type ECMap; - ECMap ecmap = (boost::is_same >::value) - //avoid constructing the Border_constraint_pmap if it's not used - ? choose_param(get_param(np, internal_np::edge_is_constrained) - , internal::Border_constraint_pmap(pmesh, faces, fimap)) - : choose_param(get_param(np, internal_np::edge_is_constrained) - , internal::Border_constraint_pmap()); + ECMap ecmap = choose_param(get_param(np, internal_np::edge_is_constrained) + , internal::No_constraint_pmap()); typedef typename boost::lookup_named_param_def < internal_np::vertex_is_constrained_t, @@ -175,29 +188,35 @@ void isotropic_remeshing(const FaceRange& faces VCMap vcmap = choose_param(get_param(np, internal_np::vertex_is_constrained), internal::No_constraint_pmap()); + bool protect = choose_param(get_param(np, internal_np::protect_constraints), false); typedef typename boost::lookup_named_param_def < internal_np::face_patch_t, NamedParameters, - internal::Connected_components_pmap//default + internal::Connected_components_pmap//default > ::type FPMap; FPMap fpmap = choose_param( get_param(np, internal_np::face_patch), - internal::Connected_components_pmap(pmesh, ecmap, fimap, - boost::is_default_param(get_param(np, internal_np::face_patch)))); + internal::Connected_components_pmap(faces, pmesh, ecmap, fimap, + boost::is_default_param(get_param(np, internal_np::face_patch)) && (need_aabb_tree +#if !defined(CGAL_NO_PRECONDITIONS) + || protect // face patch map is used to identify patch border edges to check protected edges are short enough +#endif + ) ) ); double low = 4. / 5. * target_edge_length; double high = 4. / 3. * target_edge_length; - bool protect = choose_param(get_param(np, internal_np::protect_constraints), false); +#if !defined(CGAL_NO_PRECONDITIONS) if(protect) { std::string msg("Isotropic remeshing : protect_constraints cannot be set to"); msg.append(" true with constraints larger than 4/3 * target_edge_length."); msg.append(" Remeshing aborted."); CGAL_precondition_msg( - internal::constraints_are_short_enough(pmesh, ecmap, vpmap, high), + internal::constraints_are_short_enough(pmesh, ecmap, vpmap, fpmap, high), msg.c_str()); } +#endif #ifdef CGAL_PMP_REMESHING_VERBOSE t.stop(); @@ -208,7 +227,7 @@ void isotropic_remeshing(const FaceRange& faces #endif typename internal::Incremental_remesher - remesher(pmesh, vpmap, protect, ecmap, vcmap, fpmap, fimap); + remesher(pmesh, vpmap, protect, ecmap, vcmap, fpmap, fimap, need_aabb_tree); remesher.init_remeshing(faces); #ifdef CGAL_PMP_REMESHING_VERBOSE @@ -216,6 +235,7 @@ void isotropic_remeshing(const FaceRange& faces std::cout << " done ("<< t.time() <<" sec)." << std::endl; #endif + bool collapse_constraints = choose_param(get_param(np, internal_np::collapse_constraints), true); unsigned int nb_iterations = choose_param(get_param(np, internal_np::number_of_iterations), 1); bool smoothing_1d = choose_param(get_param(np, internal_np::relax_constraints), false); unsigned int nb_laplacian = choose_param(get_param(np, internal_np::number_of_relaxation_steps), 1); @@ -235,19 +255,17 @@ void isotropic_remeshing(const FaceRange& faces if (target_edge_length>0) { remesher.split_long_edges(high); - remesher.collapse_short_edges(low, high); + remesher.collapse_short_edges(low, high, collapse_constraints); } remesher.equalize_valences(); remesher.tangential_relaxation(smoothing_1d, nb_laplacian); - remesher.project_to_surface(); - + if ( choose_param(get_param(np, internal_np::do_project), true) ) + remesher.project_to_surface(get_param(np, internal_np::projection_functor)); #ifdef CGAL_PMP_REMESHING_VERBOSE std::cout << std::endl; #endif } - remesher.update_constraints_property_map(); - #ifdef CGAL_PMP_REMESHING_VERBOSE t.stop(); std::cout << "Remeshing done (size = " << target_edge_length; @@ -296,6 +314,12 @@ void isotropic_remeshing( * \cgalParamBegin{vertex_point_map} the property map with the points associated * to the vertices of `pmesh`. Instance of a class model of `ReadWritePropertyMap`. * \cgalParamEnd +* \cgalParamBegin{face_index_map} a property map containing the index of each face of `pmesh` +* \cgalParamEnd +* \cgalParamBegin{edge_is_constrained_map} a property map containing the +* constrained-or-not status of each edge of `pmesh`. A constrained edge can be split, +* and the sub-edges are set to be constrained. +* \cgalParamEnd * \cgalNamedParamsEnd * * @sa `isotropic_remeshing()` @@ -334,13 +358,13 @@ void split_long_edges(const EdgeRange& edges typename internal::Incremental_remesher, - internal::Connected_components_pmap, + internal::Connected_components_pmap, FIMap > remesher(pmesh, vpmap, false/*protect constraints*/ , ecmap , internal::No_constraint_pmap() - , internal::Connected_components_pmap(pmesh, ecmap, fimap, false) + , internal::Connected_components_pmap(faces(pmesh), pmesh, ecmap, fimap, false) , fimap , false/*need aabb_tree*/); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h index b44a11839e8..6fcb1e929dd 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h @@ -644,7 +644,7 @@ std::size_t remove_null_edges( if ( traits.equal_3_object()(get(vpmap, target(hd, tmesh)), get(vpmap, source(hd, tmesh))) ) null_edges_to_remove.insert(edge(hd, tmesh)); - CGAL_assertion( is_valid(tmesh) ); + CGAL_assertion( is_valid_polygon_mesh(tmesh) ); } } @@ -676,7 +676,7 @@ std::size_t remove_null_edges( /// \cgalNamedParamsBegin /// \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. The type of this map is model of `ReadWritePropertyMap`. /// If this parameter is omitted, an internal property map for -/// `CGAL::vertex_point_t` should be available in `TriangleMesh` +/// `CGAL::vertex_point_t` must be available in `TriangleMesh` /// \cgalParamEnd /// \cgalParamBegin{geom_traits} a geometric traits class instance. /// The traits class must provide the nested type `Point_3`, @@ -1409,10 +1409,11 @@ remove_self_intersections_one_step(TriangleMesh& tm, // some boundary cycle of halfedges bool topology_issue = false; if (verbose) + { std::cout << " DEBUG: is_valid in one_step(tm)? "; std::cout.flush(); - std::cout << is_valid(tm) << "\n"; + std::cout << is_valid_polygon_mesh(tm) << "\n"; } if(!faces_to_remove.empty()){ @@ -1693,7 +1694,7 @@ remove_self_intersections_one_step(TriangleMesh& tm, if (verbose) { std::cout << " DEBUG: is_valid(tm) in one_step, before mesh changes? "; - std::cout << is_valid(tm) << std::endl; + std::cout << is_valid_polygon_mesh(tm) << std::endl; } //try hole_filling. @@ -1858,7 +1859,7 @@ remove_self_intersections_one_step(TriangleMesh& tm, std::cout << " DEBUG: " << cc_faces.size() << " triangles removed, " << patch.size() << " created\n"; - CGAL_assertion(is_valid(tm)); + CGAL_assertion(is_valid_polygon_mesh(tm)); something_was_done = true; } @@ -1888,13 +1889,13 @@ bool remove_self_intersections(TriangleMesh& tm, const NamedParameters& np) bool preserve_genus = boost::choose_param(boost::get_param(np, internal_np::preserve_genus), true); if (verbose) - std::cout << "DEBUG: Starting remove_self_intersections, is_valid(tm)? " << is_valid(tm) << "\n"; + std::cout << "DEBUG: Starting remove_self_intersections, is_valid(tm)? " << is_valid_polygon_mesh(tm) << "\n"; // first handle the removal of degenerate faces remove_degenerate_faces(tm, np); if (verbose) - std::cout << "DEBUG: After degenerate faces removal, is_valid(tm)? " << is_valid(tm) << "\n"; + std::cout << "DEBUG: After degenerate faces removal, is_valid(tm)? " << is_valid_polygon_mesh(tm) << "\n"; // Look for self-intersections in the polyhedron and remove them int step=-1; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h index 415a6641d4e..230870511b8 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h @@ -253,7 +253,7 @@ self_intersections( const FaceRange& face_range, * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd * @@ -312,7 +312,7 @@ self_intersections(const TriangleMesh& tmesh, OutputIterator out) * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd @@ -403,7 +403,7 @@ OutputIterator self_intersections(const FaceRange& face_range, * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `tmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `PMPSelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd * @@ -445,11 +445,11 @@ bool does_self_intersect(const TriangleMesh& tmesh * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `tmesh`. * If this parameter is omitted, an internal property map for - * `CGAL::vertex_point_t` should be available in `TriangleMesh`\cgalParamEnd + * `CGAL::vertex_point_t` must be available in `TriangleMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} an instance of a geometric traits class, model of `SelfIntersectionTraits` \cgalParamEnd * \cgalNamedParamsEnd * - * @return true if the faces in `face_range` self-intersects + * @return true if the faces in `face_range` self-intersect */ template diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/transform.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/transform.h new file mode 100644 index 00000000000..efff419092c --- /dev/null +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/transform.h @@ -0,0 +1,77 @@ +// Copyright (c) 2018 GeometryFactory (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// +// Author(s) : Maxime Gimeno +#ifndef CGAL_POLYGON_MESH_PROCESSING_TRANSFORM_H +#define CGAL_POLYGON_MESH_PROCESSING_TRANSFORM_H +#include + +#include +#include + +namespace CGAL{ +namespace Polygon_mesh_processing{ +/** + * \ingroup PkgPolygonMeshProcessing + * applies a transformation to every vertex of a `PolygonMesh`. + * + * @tparam Transformation a functor that has an `operator()(Point_3)`, with `Point_3` + * the `value_type` of `vertex_point_map` (see below). Such a functor can be + * `CGAL::Aff_transformation_3` for example. + * @tparam PolygonMesh a model of `VertexListGraph` + * @tparam NamedParameters a sequence of \ref pmp_namedparameters "Named Parameters" + * + * @param transformation the transformation functor to apply to the points of `mesh`. + * @param mesh the `PolygonMesh` to transform. + * @param np optional sequence of \ref pmp_namedparameters for `mesh`, among the ones listed below + * + * * \cgalNamedParamsBegin + * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `mesh`. + * If this parameter is omitted, an internal property map for + * `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd + * \cgalNamedParamsEnd + * + */ +template +void transform(const Transformation& transformation, + PolygonMesh& mesh, + const NamedParameters& np) +{ + typedef typename GetVertexPointMap::type VPMap; + VPMap vpm = choose_param(get_param(np, internal_np::vertex_point), + get_property_map(vertex_point, mesh)); + + BOOST_FOREACH(typename boost::graph_traits::vertex_descriptor vd, vertices(mesh)) + { + put(vpm, vd, transformation(get(vpm, vd))); + } +} + +/// \cond SKIP_IN_MANUAL +template +void transform(const Transformation& transformation, + PolygonMesh& mesh) +{ + transform(transformation, mesh, parameters::all_default()); +} +/// \endcond +} +} + +#endif diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/triangulate_faces.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/triangulate_faces.h index 5c4c5fad8ab..be59a7eb69a 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/triangulate_faces.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/triangulate_faces.h @@ -412,7 +412,7 @@ public: * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for -* `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd +* `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} a geometric traits class instance \cgalParamEnd * \cgalNamedParamsEnd * @@ -464,7 +464,7 @@ bool triangulate_face(typename boost::graph_traits::face_descriptor * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for -* `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd +* `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} a geometric traits class instance \cgalParamEnd * \cgalNamedParamsEnd * @@ -511,7 +511,7 @@ bool triangulate_faces(FaceRange face_range, PolygonMesh& pmesh) * \cgalNamedParamsBegin * \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. * If this parameter is omitted, an internal property map for -* `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd +* `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd * \cgalParamBegin{geom_traits} a geometric traits class instance \cgalParamEnd * \cgalNamedParamsEnd * diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/triangulate_hole.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/triangulate_hole.h index ffd95e7cc6a..24c2983604b 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/triangulate_hole.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/triangulate_hole.h @@ -64,7 +64,7 @@ namespace Polygon_mesh_processing { \cgalNamedParamsBegin \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `pmesh`. If this parameter is omitted, an internal property map for - `CGAL::vertex_point_t` should be available in `PolygonMesh`\cgalParamEnd + `CGAL::vertex_point_t` must be available in `PolygonMesh`\cgalParamEnd \cgalParamBegin{use_delaunay_triangulation} if `true`, use the Delaunay triangulation facet search space \cgalParamEnd \cgalParamBegin{geom_traits} a geometric traits class instance \cgalParamEnd \cgalNamedParamsEnd diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt index bad4e3eceb6..f7af9794708 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/CMakeLists.txt @@ -99,6 +99,7 @@ endif() create_single_source_cgal_program("triangulate_hole_polyline_test.cpp") create_single_source_cgal_program("surface_intersection_sm_poly.cpp" ) create_single_source_cgal_program("test_orient_cc.cpp") + create_single_source_cgal_program("test_pmp_transform.cpp") if( TBB_FOUND ) CGAL_target_use_TBB(test_pmp_distance) diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/fairing_test.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/fairing_test.cpp index dfbff75feb6..b3eff2f4aab 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/fairing_test.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/fairing_test.cpp @@ -1,8 +1,6 @@ #include #include #include -#include -#include #include diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/orient_polygon_soup_test.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/orient_polygon_soup_test.cpp index a763b6b8128..eabf7f14538 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/orient_polygon_soup_test.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/orient_polygon_soup_test.cpp @@ -2,13 +2,11 @@ #include #include -#include #include #include #include -#include #include #include diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/point_inside_polyhedron_boundary_test.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/point_inside_polyhedron_boundary_test.cpp index e4ce28785ae..d2081853d35 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/point_inside_polyhedron_boundary_test.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/point_inside_polyhedron_boundary_test.cpp @@ -2,8 +2,6 @@ #include #include #include -#include -#include #include "point_inside_helpers.h" diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/polygon_mesh_slicer_test.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/polygon_mesh_slicer_test.cpp index 6d6820b9288..a08b5302938 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/polygon_mesh_slicer_test.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/polygon_mesh_slicer_test.cpp @@ -4,11 +4,8 @@ #include #ifdef USE_SURFACE_MESH #include -#include #else #include -#include -#include #endif #include diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/remove_degeneracies_test.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/remove_degeneracies_test.cpp index 70c7162e773..386e27723a1 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/remove_degeneracies_test.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/remove_degeneracies_test.cpp @@ -26,7 +26,7 @@ void fix(const char* fname) } CGAL::Polygon_mesh_processing::remove_degenerate_faces(mesh); - assert( CGAL::is_valid(mesh) ); + assert( CGAL::is_valid_polygon_mesh(mesh) ); } int main() diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/surface_intersection_sm_poly.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/surface_intersection_sm_poly.cpp index c362b06b61e..154b56bd6d4 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/surface_intersection_sm_poly.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/surface_intersection_sm_poly.cpp @@ -2,8 +2,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_corefinement_bool_op.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_corefinement_bool_op.cpp index 6b1d61c739d..29501f793ea 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_corefinement_bool_op.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_corefinement_bool_op.cpp @@ -7,7 +7,6 @@ #include #include -#include #include #include diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_detect_features.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_detect_features.cpp index 2e88a149549..7199a5f4e58 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_detect_features.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_detect_features.cpp @@ -49,6 +49,7 @@ int main(int argc, char* argv[]) = PMP::sharp_edges_segmentation(mesh, 90, eif, pid, PMP::parameters::first_index(1) .vertex_incident_patches_map(vip)); + CGAL_assertion(number_of_patches == 6); PMP::detect_sharp_edges(mesh, 90, eif); @@ -89,3 +90,4 @@ int main(int argc, char* argv[]) return 0; } + diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_is_polygon_soup_a_polygon_mesh.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_is_polygon_soup_a_polygon_mesh.cpp index 06197919b57..edfc4802110 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_is_polygon_soup_a_polygon_mesh.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_is_polygon_soup_a_polygon_mesh.cpp @@ -1,5 +1,4 @@ #include -#include #include #include diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_distance.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_distance.cpp index ca4ca98e7fe..08936586a6f 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_distance.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_distance.cpp @@ -210,7 +210,7 @@ struct Real_embeddable_traits< Custom_traits_Hausdorff::FT > : public INTERN_RET::Real_embeddable_traits_base< Custom_traits_Hausdorff::FT , CGAL::Tag_true> { class To_double - : public CGAL::unary_function< Custom_traits_Hausdorff::FT, double > { + : public CGAL::cpp98::unary_function< Custom_traits_Hausdorff::FT, double > { public: double operator()( const Custom_traits_Hausdorff::FT& ) const { return 0; } }; diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_remove_border_edge.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_remove_border_edge.cpp index 2fa0e4cef27..a8be4b4b5a8 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_remove_border_edge.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_remove_border_edge.cpp @@ -1,8 +1,6 @@ #include #include #include -#include -#include #include #include @@ -32,7 +30,7 @@ void test_middle_edge() CGAL_assertion( h!=GT::null_halfedge() ); CGAL::Polygon_mesh_processing::remove_a_border_edge(edge(h,tm), tm); - CGAL_assertion(is_valid(tm)); + CGAL_assertion(is_valid_polygon_mesh(tm)); CGAL_assertion(is_triangle_mesh(tm)); std::ofstream out("edge_middle_out.off"); out << tm; @@ -58,7 +56,7 @@ void test_edge_border_case1() CGAL_assertion( h!=GT::null_halfedge() ); CGAL::Polygon_mesh_processing::remove_a_border_edge(edge(h,tm), tm); - CGAL_assertion(is_valid(tm)); + CGAL_assertion(is_valid_polygon_mesh(tm)); CGAL_assertion(is_triangle_mesh(tm)); std::ofstream out("edge_border_case1_out.off"); out << tm; @@ -84,7 +82,7 @@ void test_edge_border_case2() CGAL_assertion( h!=GT::null_halfedge() ); CGAL::Polygon_mesh_processing::remove_a_border_edge(edge(h,tm), tm); - CGAL_assertion(is_valid(tm)); + CGAL_assertion(is_valid_polygon_mesh(tm)); CGAL_assertion(is_triangle_mesh(tm)); std::ofstream out("edge_border_case2_out.off"); out << tm; diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_transform.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_transform.cpp new file mode 100644 index 00000000000..fe1532db11b --- /dev/null +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_transform.cpp @@ -0,0 +1,33 @@ +#include +#include +#include +#include + +#include +#include + + + +namespace PMP = CGAL::Polygon_mesh_processing; +namespace params = PMP::parameters; +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef K::Point_3 Point; +typedef CGAL::Surface_mesh Mesh; + + + +int main() +{ + Mesh m; + CGAL::make_tetrahedron(Point(0,0,0), Point(0,0,1), Point(0,1,2), Point(1,0,3), m); + CGAL::Aff_transformation_3 trans(0,0,0,1,0,1,0,0,0,0,1,1); + PMP::transform(trans, m, params::all_default()); + bool ok = true; + for(Mesh::size_type i = 0; i #include #include -#include -#include #include #include @@ -54,7 +52,7 @@ void test_surface_mesh(const char* fname) CGAL::Polygon_mesh_processing::stitch_borders(m); //todo : add a validity test - assert(is_valid(m)); + assert(is_valid_polygon_mesh(m)); std::cout << "OK\n"; } diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_faces_test.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_faces_test.cpp index 33d2e65f3c4..a301cb0e2d6 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_faces_test.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_faces_test.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_Polyhedron_3_no_delaunay_test.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_Polyhedron_3_no_delaunay_test.cpp index e3c7b62d9b6..213cfa95b5a 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_Polyhedron_3_no_delaunay_test.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_Polyhedron_3_no_delaunay_test.cpp @@ -5,13 +5,8 @@ #include #ifdef POLY #include -#include -#include -#include #else #include -#include -#include #endif #include diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_Polyhedron_3_test.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_Polyhedron_3_test.cpp index 4003415e2e4..afff2c7acba 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_Polyhedron_3_test.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_Polyhedron_3_test.cpp @@ -3,13 +3,8 @@ #include #ifdef POLY #include -#include -#include -#include #else #include -#include -#include #endif #include diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_polyline_test.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_polyline_test.cpp index c6998746633..16cfe36105a 100644 --- a/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_polyline_test.cpp +++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/triangulate_hole_polyline_test.cpp @@ -9,9 +9,6 @@ #include #include -#include -#include -#include #include diff --git a/Polyhedron/demo/Polyhedron/C3t3_type.h b/Polyhedron/demo/Polyhedron/C3t3_type.h index d3e09ef5380..d059f437a35 100644 --- a/Polyhedron/demo/Polyhedron/C3t3_type.h +++ b/Polyhedron/demo/Polyhedron/C3t3_type.h @@ -3,20 +3,18 @@ // include this to get #define BOOST_PARAMETER_MAX_ARITY 12 // as otherwise it gets set via inclusion of Polyhedron_3.h -#include +#include #include #include "Polyhedron_type.h" #include "SMesh_type.h" #ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES #include "Image_type.h" -#include +#include #include -#include "Polyhedron_demo_mesh_3_labeled_mesh_domain_3.h" #endif #ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS #include "implicit_functions/Implicit_function_interface.h" -#include "Polyhedron_demo_mesh_3_labeled_mesh_domain_3.h" #endif #include @@ -55,14 +53,12 @@ typedef CGAL::Polyhedral_mesh_domain_with_features_3< // The last `Tag_true` says the Patch_id type will be int, and not pair #ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES -typedef CGAL::Labeled_image_mesh_domain_3 Image_domain1; -typedef CGAL::Polyhedron_demo_labeled_mesh_domain_3 Image_domain; +typedef CGAL::Labeled_mesh_domain_3 Image_domain; typedef CGAL::Mesh_domain_with_polyline_features_3 Image_mesh_domain; #endif #ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS typedef Wrapper Function_wrapper; -typedef CGAL::Labeled_mesh_domain_3 Function_domain; -typedef CGAL::Polyhedron_demo_labeled_mesh_domain_3 Function_mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Function_mesh_domain; #endif //Robust_cc_geom_traits diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index 4e1926194a9..47b9048b765 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -66,13 +66,10 @@ find_package(Qt5 # Find OpenGL find_package(OpenGL) -# Find QGLViewer if(Qt5_FOUND) add_definitions(-DQT_NO_KEYWORDS) add_definitions(-DSCENE_IMAGE_GL_BUFFERS_AVAILABLE) - find_package(QGLViewer ) - endif(Qt5_FOUND) find_package(Eigen3 3.2.0) #(requires 3.2.0 or greater) @@ -126,19 +123,17 @@ endif() -if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) +if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND ) set(Boost_USE_MULTITHREADED ON) find_package(Boost COMPONENTS thread system filesystem) - include_directories ( ${QGLVIEWER_INCLUDE_DIR} ) qt5_wrap_ui( MainWindowUI_files MainWindow.ui) qt5_wrap_ui( statisticsUI_FILES Statistics_on_item_dialog.ui) qt5_wrap_ui( FileLoaderDialogUI_files FileLoaderDialog.ui ) qt5_wrap_ui( Show_point_dialogUI_FILES Show_point_dialog.ui ) qt5_wrap_ui( PreferencesUI_FILES Preferences.ui ) qt5_wrap_ui( Show_point_dialogUI_FILES Show_point_dialog.ui ) - qt5_wrap_ui( ViewerUI_FILES ImageInterface.ui) qt5_generate_moc( "File_loader_dialog.h" "${CMAKE_CURRENT_BINARY_DIR}/File_loader_dialog_moc.cpp" ) include( ${CMAKE_CURRENT_SOURCE_DIR}/polyhedron_demo_macros.cmake ) @@ -188,7 +183,6 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) Polyhedron_demo_plugin_helper.cpp) target_link_libraries(demo_framework PUBLIC Qt5::OpenGL Qt5::Widgets Qt5::Gui Qt5::Script - ${QGLVIEWER_LIBRARIES} ) if(CGAL_HEADER_ONLY) target_compile_definitions(demo_framework PRIVATE -DCGAL_USE_Qt5_RESOURCES) @@ -202,7 +196,6 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) PUBLIC demo_framework ${CGAL_LIBRARIES} - ${QGLVIEWER_LIBRARIES} Qt5::OpenGL Qt5::Gui Qt5::Script Qt5::Widgets) add_library(scene_color_ramp SHARED Color_ramp.cpp) target_link_libraries(scene_color_ramp PRIVATE Qt5::Core) @@ -219,7 +212,6 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) cgal_add_compilation_test(${item_name}) endmacro(add_item) - add_item(scene_c2t3_item Scene_c2t3_item.cpp) add_item(scene_c3t3_item Scene_c3t3_item.cpp) target_link_libraries(scene_c3t3_item PUBLIC scene_polyhedron_item scene_polygon_soup_item scene_basic_objects ${TBB_LIBRARIES}) if(TBB_FOUND) @@ -344,9 +336,6 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) # Link with CGAL target_link_libraries( Polyhedron_3 PUBLIC ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} ) - # Link with libQGLViewer - target_link_libraries( Polyhedron_3 PUBLIC ${QGLVIEWER_LIBRARIES}) - add_to_cached_list( CGAL_EXECUTABLE_TARGETS Polyhedron_3 ) @@ -404,7 +393,7 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) configure_file(CGAL_polyhedron_demoConfig.cmake.in CGAL_polyhedron_demoConfig.cmake) #TO DO script the activation of all the plugins. -else (CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) +else (CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND ) set(POLYHEDRON_MISSING_DEPS "") @@ -420,11 +409,7 @@ else (CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) set(POLYHEDRON_MISSING_DEPS "OpenGL, ${POLYHEDRON_MISSING_DEPS}") endif() - if(NOT QGLVIEWER_FOUND) - set(POLYHEDRON_MISSING_DEPS "QGLViewer, ${POLYHEDRON_MISSING_DEPS}") - endif() - message(STATUS "NOTICE: This demo requires ${POLYHEDRON_MISSING_DEPS}and will not be compiled.") -endif (CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) +endif (CGAL_Qt5_FOUND AND Qt5_FOUND AND OPENGL_FOUND ) diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 168fdae6cfb..9fcb2ffb6c9 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -53,8 +53,8 @@ #include "Show_point_dialog.h" #include "File_loader_dialog.h" -#include -#include +#include +#include #ifdef QT_SCRIPT_LIB # include @@ -771,42 +771,34 @@ void MainWindow::viewerShow(float xmin, float ymax, float zmax) { - qglviewer::Vec + CGAL::qglviewer::Vec min_(xmin, ymin, zmin), max_(xmax, ymax, zmax); if(min_ == max_) return viewerShow(xmin, ymin, zmin); -#if QGLVIEWER_VERSION >= 0x020502 viewer->camera()->setPivotPoint((min_+max_)*0.5); -#else - viewer->camera()->setRevolveAroundPoint((min_+max_)*0.5); -#endif - qglviewer::ManipulatedCameraFrame backup_frame(*viewer->camera()->frame()); + CGAL::qglviewer::ManipulatedCameraFrame backup_frame(*viewer->camera()->frame()); viewer->camera()->fitBoundingBox(min_, max_); - qglviewer::ManipulatedCameraFrame new_frame(*viewer->camera()->frame()); + CGAL::qglviewer::ManipulatedCameraFrame new_frame(*viewer->camera()->frame()); *viewer->camera()->frame() = backup_frame; viewer->camera()->interpolateTo(new_frame, 1.f); viewer->setVisualHintsMask(1); } void MainWindow::viewerShow(float x, float y, float z) { - // viewer->camera()->lookAt(qglviewer::Vec(x, y, z)); + // viewer->camera()->lookAt(CGAL::qglviewer::Vec(x, y, z)); - qglviewer::ManipulatedCameraFrame backup_frame(*viewer->camera()->frame()); - viewer->camera()->fitSphere(qglviewer::Vec(x, y, z), + CGAL::qglviewer::ManipulatedCameraFrame backup_frame(*viewer->camera()->frame()); + viewer->camera()->fitSphere(CGAL::qglviewer::Vec(x, y, z), viewer->camera()->sceneRadius()/100); - qglviewer::ManipulatedCameraFrame new_frame(*viewer->camera()->frame()); + CGAL::qglviewer::ManipulatedCameraFrame new_frame(*viewer->camera()->frame()); *viewer->camera()->frame() = backup_frame; viewer->camera()->interpolateTo(new_frame, 1.f); viewer->setVisualHintsMask(1); -#if QGLVIEWER_VERSION >= 0x020502 - viewer->camera()->setPivotPoint(qglviewer::Vec(x, y, z)); -#else - viewer->camera()->setRevolveAroundPoint(qglviewer::Vec(x, y, z)); -#endif + viewer->camera()->setPivotPoint(CGAL::qglviewer::Vec(x, y, z)); } void MainWindow::message(QString message, QString colorName, QString font) { @@ -840,11 +832,7 @@ void MainWindow::error(QString text) { void MainWindow::updateViewerBBox(bool recenter = true) { const Scene::Bbox bbox = scene->bbox(); -#if QGLVIEWER_VERSION >= 0x020502 - qglviewer::Vec center = viewer->camera()->pivotPoint(); -#else - qglviewer::Vec center = viewer->camera()->revolveAroundPoint(); -#endif + CGAL::qglviewer::Vec center = viewer->camera()->pivotPoint(); const double xmin = bbox.xmin(); const double ymin = bbox.ymin(); const double zmin = bbox.zmin(); @@ -853,11 +841,11 @@ void MainWindow::updateViewerBBox(bool recenter = true) const double zmax = bbox.zmax(); - qglviewer::Vec + CGAL::qglviewer::Vec vec_min(xmin, ymin, zmin), vec_max(xmax, ymax, zmax), bbox_center((xmin+xmax)/2, (ymin+ymax)/2, (zmin+zmax)/2); - qglviewer::Vec offset(0,0,0); + CGAL::qglviewer::Vec offset(0,0,0); double l_dist = (std::max)((std::abs)(bbox_center.x - viewer->offset().x), (std::max)((std::abs)(bbox_center.y - viewer->offset().y), (std::abs)(bbox_center.z - viewer->offset().z))); @@ -886,11 +874,7 @@ void MainWindow::updateViewerBBox(bool recenter = true) } else { -#if QGLVIEWER_VERSION >= 0x020502 viewer->camera()->setPivotPoint(center); -#else - viewer->camera()->setRevolveAroundPoint(center); -#endif } } @@ -1700,7 +1684,7 @@ void MainWindow::save(QString filename, CGAL::Three::Scene_item* item) { void MainWindow::on_actionSaveSnapshot_triggered() { - viewer->saveSnapshot(false); + viewer->saveSnapshot(); } bool MainWindow::on_actionErase_triggered() @@ -2120,6 +2104,8 @@ void MainWindow::insertActionBeforeLoadPlugin(QMenu* menu, QAction* actionToInse void MainWindow::colorItems() { std::size_t nb_files = scene->selectionIndices().size(); + if(nb_files<2) + return; std::vector colors_; colors_.reserve(nb_files); compute_color_map(scene->item(scene->selectionIndices().last())->color(), diff --git a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp index 4c0c77d3096..01aab6b0163 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/AABB_tree/Cut_plugin.cpp @@ -83,11 +83,11 @@ class FillGridSize { std::vector&trees; std::vector&sm_trees; bool is_signed; - qglviewer::ManipulatedFrame* frame; + CGAL::qglviewer::ManipulatedFrame* frame; public: FillGridSize(std::size_t grid_size, FT diag, Point_distance (&distance_function)[100][100], FT& max_distance_function, std::vector& trees, std::vector& sm_trees, - bool is_signed, qglviewer::ManipulatedFrame* frame) + bool is_signed, CGAL::qglviewer::ManipulatedFrame* frame) : grid_size(grid_size), distance_function (distance_function), diag(diag), max_distance_function(max_distance_function), trees(trees), sm_trees(sm_trees), is_signed(is_signed), frame(frame) @@ -112,7 +112,7 @@ public: FT x = -diag/fd + FT(i)/FT(grid_size) * dx; { FT y = -diag/fd + FT(j)/FT(grid_size) * dy; - const qglviewer::Vec v_offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec v_offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); Simple_kernel::Vector_3 offset(v_offset.x, v_offset.y, v_offset.z); Point query = transfo( Point(x,y,z))-offset; FT min = DBL_MAX; @@ -256,7 +256,7 @@ class Q_DECL_EXPORT Scene_aabb_item : public CGAL::Three::Scene_item public: Scene_aabb_item(const Facet_tree& tree) : CGAL::Three::Scene_item(1,1) { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); positions_lines.clear(); CGAL::AABB_drawing_traits > traits; @@ -281,7 +281,7 @@ public: Scene_aabb_item(const Facet_sm_tree& tree) : CGAL::Three::Scene_item(1,1) { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); positions_lines.clear(); CGAL::AABB_drawing_traits > traits; @@ -476,7 +476,7 @@ private: } void computeElements() const { - const qglviewer::Vec v_offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec v_offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); Simple_kernel::Vector_3 offset(v_offset.x, v_offset.y, v_offset.z); QApplication::setOverrideCursor(Qt::WaitCursor); positions_lines.clear(); @@ -1225,7 +1225,7 @@ void Polyhedron_demo_cut_plugin::init(QMainWindow* mainWindow, connect(real_scene, SIGNAL(newItem(int)), this, SLOT(updateTrees(int))); - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); viewer->installEventFilter(this); _actions << actionIntersection @@ -1443,10 +1443,10 @@ void Polyhedron_demo_cut_plugin::computeIntersection() scene->addItem(edges_item); } - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); - const qglviewer::Vec& pos = plane_item->manipulatedFrame()->position() - offset; - const qglviewer::Vec& n = - plane_item->manipulatedFrame()->inverseTransformOf(qglviewer::Vec(0.f, 0.f, 1.f)); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec& pos = plane_item->manipulatedFrame()->position() - offset; + const CGAL::qglviewer::Vec& n = + plane_item->manipulatedFrame()->inverseTransformOf(CGAL::qglviewer::Vec(0.f, 0.f, 1.f)); Simple_kernel::Plane_3 plane(n[0], n[1], n[2], - n * pos); //std::cerr << plane << std::endl; edges_item->edges.clear(); diff --git a/Polyhedron/demo/Polyhedron/Plugins/Camera_position/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/Camera_position/CMakeLists.txt index cc5cc80dd7b..f246111ba87 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Camera_position/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/Camera_position/CMakeLists.txt @@ -5,5 +5,5 @@ include( polyhedron_demo_macros ) Camera_positions_list ${cameraUI_FILES}) - target_link_libraries( camera_positions_plugin PUBLIC ${QGLVIEWER_LIBRARIES} demo_framework) + target_link_libraries( camera_positions_plugin PUBLIC demo_framework) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_list.cpp b/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_list.cpp index 81c73f2ed0a..55723dd273d 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_list.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Camera_position/Camera_positions_list.cpp @@ -134,7 +134,7 @@ void Camera_positions_list::load(QString filename) { QString text = input.readLine(1000); QString coord = input.readLine(1000); if(text.isNull() || coord.isNull()) return; - qglviewer::Frame frame; + CGAL::qglviewer::Frame frame; if(m_viewer->readFrame(coord, frame)) { addItem(text, @@ -145,15 +145,11 @@ void Camera_positions_list::load(QString filename) { void Camera_positions_list::on_frontButton_pressed() { - qglviewer::Vec posFront = qglviewer::Vec(0,0,m_viewer->sceneRadius()/(sin (m_viewer->camera()->fieldOfView()/2))); -#if QGLVIEWER_VERSION >= 0x020502 - qglviewer::Vec trans = m_viewer->camera()->pivotPoint(); -#else - qglviewer::Vec trans = m_viewer->camera()->revolveAroundPoint(); -#endif + CGAL::qglviewer::Vec posFront = CGAL::qglviewer::Vec(0,0,m_viewer->sceneRadius()/(sin (m_viewer->camera()->fieldOfView()/2))); + CGAL::qglviewer::Vec trans = m_viewer->camera()->pivotPoint(); posFront = posFront + trans; - qglviewer::Quaternion dirFront; - dirFront.setAxisAngle(qglviewer::Vec(0,1,0),0); + CGAL::qglviewer::Quaternion dirFront; + dirFront.setAxisAngle(CGAL::qglviewer::Vec(0,1,0),0); QString frontCoord = QString("%1 %2 %3 %4 %5 %6 %7") .arg(posFront[0]) .arg(posFront[1]) @@ -168,15 +164,11 @@ void Camera_positions_list::on_frontButton_pressed() void Camera_positions_list::on_backButton_pressed() { - qglviewer::Vec posBack = qglviewer::Vec(0,0,-m_viewer->sceneRadius()/(sin (m_viewer->camera()->fieldOfView()/2))); -#if QGLVIEWER_VERSION >= 0x020502 - qglviewer::Vec trans = m_viewer->camera()->pivotPoint(); -#else - qglviewer::Vec trans = m_viewer->camera()->revolveAroundPoint(); -#endif + CGAL::qglviewer::Vec posBack = CGAL::qglviewer::Vec(0,0,-m_viewer->sceneRadius()/(sin (m_viewer->camera()->fieldOfView()/2))); + CGAL::qglviewer::Vec trans = m_viewer->camera()->pivotPoint(); posBack+= trans; - qglviewer::Quaternion dirBack; - dirBack.setAxisAngle(qglviewer::Vec(0,1,0),CGAL_PI); + CGAL::qglviewer::Quaternion dirBack; + dirBack.setAxisAngle(CGAL::qglviewer::Vec(0,1,0),CGAL_PI); QString backCoord = QString("%1 %2 %3 %4 %5 %6 %7") .arg(posBack[0]) .arg(posBack[1]) @@ -190,15 +182,11 @@ void Camera_positions_list::on_backButton_pressed() void Camera_positions_list::on_topButton_pressed() { - qglviewer::Vec posTop = qglviewer::Vec(0,m_viewer->sceneRadius()/(sin (m_viewer->camera()->fieldOfView()/2)), 0); -#if QGLVIEWER_VERSION >= 0x020502 - qglviewer::Vec trans = m_viewer->camera()->pivotPoint(); -#else - qglviewer::Vec trans = m_viewer->camera()->revolveAroundPoint(); -#endif + CGAL::qglviewer::Vec posTop = CGAL::qglviewer::Vec(0,m_viewer->sceneRadius()/(sin (m_viewer->camera()->fieldOfView()/2)), 0); + CGAL::qglviewer::Vec trans = m_viewer->camera()->pivotPoint(); posTop += trans; - qglviewer::Quaternion dirTop; - dirTop.setAxisAngle(qglviewer::Vec(1,0,0), -CGAL_PI/2); + CGAL::qglviewer::Quaternion dirTop; + dirTop.setAxisAngle(CGAL::qglviewer::Vec(1,0,0), -CGAL_PI/2); QString topCoord = QString("%1 %2 %3 %4 %5 %6 %7") .arg(posTop[0]) .arg(posTop[1]) @@ -212,15 +200,11 @@ void Camera_positions_list::on_topButton_pressed() void Camera_positions_list::on_botButton_pressed() { - qglviewer::Vec posBot = qglviewer::Vec(0,-m_viewer->sceneRadius()/(sin (m_viewer->camera()->fieldOfView()/2)), 0);; -#if QGLVIEWER_VERSION >= 0x020502 - qglviewer::Vec trans = m_viewer->camera()->pivotPoint(); -#else - qglviewer::Vec trans = m_viewer->camera()->revolveAroundPoint(); -#endif + CGAL::qglviewer::Vec posBot = CGAL::qglviewer::Vec(0,-m_viewer->sceneRadius()/(sin (m_viewer->camera()->fieldOfView()/2)), 0);; + CGAL::qglviewer::Vec trans = m_viewer->camera()->pivotPoint(); posBot += trans; - qglviewer::Quaternion dirBot; - dirBot.setAxisAngle(qglviewer::Vec(1,0,0),CGAL_PI/2); + CGAL::qglviewer::Quaternion dirBot; + dirBot.setAxisAngle(CGAL::qglviewer::Vec(1,0,0),CGAL_PI/2); QString botCoord = QString("%1 %2 %3 %4 %5 %6 %7") .arg(posBot[0]) .arg(posBot[1]) @@ -234,15 +218,11 @@ void Camera_positions_list::on_botButton_pressed() void Camera_positions_list::on_leftButton_pressed() { - qglviewer::Vec posLeft = qglviewer::Vec(-m_viewer->sceneRadius()/(sin (m_viewer->camera()->fieldOfView()/2)), 0, 0);; -#if QGLVIEWER_VERSION >= 0x020502 - qglviewer::Vec trans = m_viewer->camera()->pivotPoint(); -#else - qglviewer::Vec trans = m_viewer->camera()->revolveAroundPoint(); -#endif + CGAL::qglviewer::Vec posLeft = CGAL::qglviewer::Vec(-m_viewer->sceneRadius()/(sin (m_viewer->camera()->fieldOfView()/2)), 0, 0);; + CGAL::qglviewer::Vec trans = m_viewer->camera()->pivotPoint(); posLeft += trans; - qglviewer::Quaternion dirLeft; - dirLeft.setAxisAngle(qglviewer::Vec(0,1,0),-CGAL_PI/2); + CGAL::qglviewer::Quaternion dirLeft; + dirLeft.setAxisAngle(CGAL::qglviewer::Vec(0,1,0),-CGAL_PI/2); QString leftCoord = QString("%1 %2 %3 %4 %5 %6 %7") .arg(posLeft[0]) .arg(posLeft[1]) @@ -256,15 +236,11 @@ void Camera_positions_list::on_leftButton_pressed() void Camera_positions_list::on_rightButton_pressed() { - qglviewer::Vec posRight = qglviewer::Vec(m_viewer->sceneRadius()/(sin (m_viewer->camera()->fieldOfView()/2)), 0,0); -#if QGLVIEWER_VERSION >= 0x020502 - qglviewer::Vec trans = m_viewer->camera()->pivotPoint(); -#else - qglviewer::Vec trans = m_viewer->camera()->revolveAroundPoint(); -#endif + CGAL::qglviewer::Vec posRight = CGAL::qglviewer::Vec(m_viewer->sceneRadius()/(sin (m_viewer->camera()->fieldOfView()/2)), 0,0); + CGAL::qglviewer::Vec trans = m_viewer->camera()->pivotPoint(); posRight += trans; - qglviewer::Quaternion dirRight; - dirRight.setAxisAngle(qglviewer::Vec(0,1,0),CGAL_PI/2); + CGAL::qglviewer::Quaternion dirRight; + dirRight.setAxisAngle(CGAL::qglviewer::Vec(0,1,0),CGAL_PI/2); QString rightCoord = QString("%1 %2 %3 %4 %5 %6 %7") .arg(posRight[0]) .arg(posRight[1]) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Classification/Classification_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Classification/Classification_plugin.cpp index b8cbbf41262..5dc092979e5 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Classification/Classification_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Classification/Classification_plugin.cpp @@ -1,8 +1,8 @@ #include #include #include -#include -#include +#include +#include #include #include "opengl_tools.h" @@ -1018,29 +1018,18 @@ public Q_SLOTS: classif->select_random_region(); item_changed(classif->item()); - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); CGAL::Bbox_3 bbox = classif->bbox(); - const qglviewer::Vec offset = static_cast(viewer)->offset(); + const CGAL::qglviewer::Vec offset = static_cast(viewer)->offset(); - viewer->camera()->fitBoundingBox(qglviewer::Vec (bbox.xmin(), bbox.ymin(), bbox.zmin()) + offset, - qglviewer::Vec (bbox.xmax(), bbox.ymax(), bbox.zmax()) + offset); + viewer->camera()->fitBoundingBox(CGAL::qglviewer::Vec (bbox.xmin(), bbox.ymin(), bbox.zmin()) + offset, + CGAL::qglviewer::Vec (bbox.xmax(), bbox.ymax(), bbox.zmax()) + offset); - // viewer->camera()->showEntireScene(); - - // bbox = scene->bbox(); - // viewer->setSceneBoundingBox(qglviewer::Vec (bbox.xmin(), bbox.ymin(), bbox.zmin()), - // qglviewer::Vec (bbox.xmax(), bbox.ymax(), bbox.zmax())); -#if QGLVIEWER_VERSION >= 0x020502 - viewer->camera()->setPivotPoint (qglviewer::Vec ((bbox.xmin() + bbox.xmax()) / 2., + + viewer->camera()->setPivotPoint (CGAL::qglviewer::Vec ((bbox.xmin() + bbox.xmax()) / 2., (bbox.ymin() + bbox.ymax()) / 2., (bbox.zmin() + bbox.zmax()) / 2.) + offset); -#else - viewer->camera()->setRevolveAroundPoint (qglviewer::Vec ((bbox.xmin() + bbox.xmax()) / 2., - (bbox.ymin() + bbox.ymax()) / 2., - (bbox.zmin() + bbox.zmax()) / 2.) + offset); -#endif - } void on_train_clicked() diff --git a/Polyhedron/demo/Polyhedron/Plugins/Classification/Cluster_classification.h b/Polyhedron/demo/Polyhedron/Plugins/Classification/Cluster_classification.h index 26c2a5c40fd..62710b88f18 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Classification/Cluster_classification.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Classification/Cluster_classification.h @@ -55,8 +55,8 @@ class Cluster_classification : public Item_classification_base }; struct Point_set_with_cluster_info - : public CGAL::unary_function > + : public CGAL::cpp98::unary_function > { Point_set* point_set; Point_set::Property_map* cluster_id; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Display/Display_property_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Display/Display_property_plugin.cpp index 2792367015c..1760befbfea 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Display/Display_property_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Display/Display_property_plugin.cpp @@ -471,7 +471,7 @@ private Q_SLOTS: { ::zoomToId(*item->face_graph(), QString("f%1").arg(angles_min[item].second), - qobject_cast(QGLViewer::QGLViewerPool().first()), + qobject_cast(CGAL::QGLViewer::QGLViewerPool().first()), dummy_fd, dummy_p); } @@ -480,7 +480,7 @@ private Q_SLOTS: { ::zoomToId(*item->face_graph(), QString("f%1").arg(jacobian_min[item].second), - qobject_cast(QGLViewer::QGLViewerPool().first()), + qobject_cast(CGAL::QGLViewer::QGLViewerPool().first()), dummy_fd, dummy_p); } @@ -504,7 +504,7 @@ private Q_SLOTS: { ::zoomToId(*item->face_graph(), QString("f%1").arg(angles_max[item].second), - qobject_cast(QGLViewer::QGLViewerPool().first()), + qobject_cast(CGAL::QGLViewer::QGLViewerPool().first()), dummy_fd, dummy_p); } @@ -513,7 +513,7 @@ private Q_SLOTS: { ::zoomToId(*item->face_graph(), QString("f%1").arg(jacobian_max[item].second), - qobject_cast(QGLViewer::QGLViewerPool().first()), + qobject_cast(CGAL::QGLViewer::QGLViewerPool().first()), dummy_fd, dummy_p); } diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt index a1fa6892011..d3c8a046946 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/CMakeLists.txt @@ -20,10 +20,10 @@ polyhedron_demo_plugin(polylines_io_plugin Polylines_io_plugin) target_link_libraries(polylines_io_plugin PUBLIC scene_polylines_item) polyhedron_demo_plugin(selection_io_plugin Selection_io_plugin) -target_link_libraries(selection_io_plugin PUBLIC scene_polyhedron_selection_item) +target_link_libraries(selection_io_plugin PUBLIC scene_polyhedron_selection_item selection_plugin) polyhedron_demo_plugin(selection_io_sm_plugin Selection_io_plugin) -target_link_libraries(selection_io_sm_plugin PUBLIC scene_surface_mesh_selection_item) +target_link_libraries(selection_io_sm_plugin PUBLIC scene_surface_mesh_selection_item selection_sm_plugin) polyhedron_demo_plugin(stl_plugin STL_io_plugin) target_link_libraries(stl_plugin PUBLIC scene_polyhedron_item scene_surface_mesh_item scene_polygon_soup_item) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_2/Mesh_2_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_2/Mesh_2_plugin.cpp index 527ec779993..acbfab9cdd5 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_2/Mesh_2_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_2/Mesh_2_plugin.cpp @@ -2,7 +2,7 @@ // Needed for lloyd_optimize_mesh_2 which does it too late // (and we don't want to spend the time on finding out who // includes the header file that sets it too a value too low -#define BOOST_PARAMETER_MAX_ARITY 8 +#define BOOST_PARAMETER_MAX_ARITY 12 #include diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_rib_exporter_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_rib_exporter_plugin.cpp index 0812d709b6f..0b188d3cd98 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_rib_exporter_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_rib_exporter_plugin.cpp @@ -65,7 +65,7 @@ private: typedef Geom_traits::FT FT; typedef Geom_traits::Aff_transformation_3 Aff_transformation_3; - typedef qglviewer::Vec qglVec; + typedef CGAL::qglviewer::Vec qglVec; enum Rib_exporter_mode { CUT=0, MESH, TRIANGULATION }; @@ -198,7 +198,7 @@ init(QMainWindow* mainWindow, Scene_interface* scene_interface, Messages_interfa viewer_ = mw->findChild("viewer"); if ( NULL == viewer_ ) { - std::cerr << "Can't get QGLViewer" << std::endl; + std::cerr << "Can't get CGAL::QGLViewer" << std::endl; } init_parameters(); diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/CMakeLists.txt index cb5e209afb6..193ee13fec7 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/CMakeLists.txt @@ -10,7 +10,7 @@ if ( Boost_VERSION GREATER 103400 ) Mesh_3_plugin_cgal_code.cpp Meshing_thread.cpp split_polylines.cpp ${meshingUI_FILES}) target_link_libraries(mesh_3_plugin PUBLIC scene_polyhedron_item scene_polygon_soup_item scene_polylines_item scene_implicit_function_item scene_image_item - scene_surface_mesh_item scene_c3t3_item ${QGLVIEWER_LIBRARIES} ${OPENGL_gl_LIBRARY} ) + scene_surface_mesh_item scene_c3t3_item ${OPENGL_gl_LIBRARY} ) set(VTK_LIBS "") find_package(VTK QUIET COMPONENTS diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp index 20eec9e8bc0..7c3ce0d2beb 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp @@ -71,8 +71,8 @@ struct IntConverter { std::pair min_max; int operator()(float f) { - float s = f * (min_max.second - min_max.first); - return s + min_max.first; + float s = f * float((min_max.second - min_max.first)); + return s + float(min_max.first); } }; @@ -123,8 +123,8 @@ class Plane_slider : public QSlider { Q_OBJECT public: - Plane_slider(const qglviewer::Vec& v, int id, Scene_interface* scene, - qglviewer::ManipulatedFrame* frame, Qt::Orientation ori, QWidget* widget) + Plane_slider(const CGAL::qglviewer::Vec& v, int id, Scene_interface* scene, + CGAL::qglviewer::ManipulatedFrame* frame, Qt::Orientation ori, QWidget* widget) : QSlider(ori, widget), v(v), id(id), scene(scene), frame(frame) { this->setTracking(true); connect(frame, SIGNAL(manipulated()), this, SLOT(updateCutPlane())); @@ -141,8 +141,8 @@ public Q_SLOTS: { if(!ready_to_move) return; - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); - qglviewer::Vec v2 = v * (this->value() / scale); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); + CGAL::qglviewer::Vec v2 = v * (this->value() / scale); v2+=offset; frame->setTranslationWithConstraint(v2); scene->itemChanged(id); @@ -153,21 +153,17 @@ public Q_SLOTS: void updateValue() { if(!ready_to_cut) return; -#if QGLVIEWER_VERSION >= 0x020600 typedef qreal qglviewer_real; -#else // QGLViewer < 2.6.0 - typedef float qglviewer_real; -#endif // QGLViewer < 2.6.0 qglviewer_real a, b, c; frame->getPosition(a, b, c); - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); a-=offset.x; b-=offset.y; c-=offset.z; float sum1 = float(a + b + c); float sum2 = float(v.x + v.y + v.z); sum1 /= sum2; - setValue(sum1 * scale); + setValue(sum1 * float(scale)); ready_to_cut = false; } @@ -184,10 +180,10 @@ private: static const unsigned int scale; bool ready_to_cut; bool ready_to_move; - qglviewer::Vec v; + CGAL::qglviewer::Vec v; int id; Scene_interface* scene; - qglviewer::ManipulatedFrame* frame; + CGAL::qglviewer::ManipulatedFrame* frame; }; const unsigned int Plane_slider::scale = 100; @@ -373,7 +369,7 @@ public Q_SLOTS: void addVP(Volume_plane_thread* thread) { Volume_plane_interface* plane = thread->getItem(); - plane->init(static_cast(QGLViewer::QGLViewerPool().first())); + plane->init(static_cast(CGAL::QGLViewer::QGLViewerPool().first())); // add the interface for this Volume_plane int id = scene->addItem(plane); scene->changeGroup(plane, group); @@ -483,7 +479,7 @@ public Q_SLOTS: } private: - qglviewer::Vec first_offset; + CGAL::qglviewer::Vec first_offset; #ifdef CGAL_USE_VTK vtkImageData* vtk_image; vtkDICOMImageReader* dicom_reader; @@ -648,7 +644,10 @@ private: Volume_plane_intersection* i = new Volume_plane_intersection(img->xdim() * img->vx()-1, img->ydim() * img->vy()-1, - img->zdim() * img->vz()-1); + img->zdim() * img->vz()-1, + img->image()->tx, + img->image()->ty, + img->image()->tz); this->intersection_id = scene->addItem(i); scene->changeGroup(i, group); group->lockChild(i); @@ -671,9 +670,9 @@ private: switchReaderConverter< Word >(minmax); - Volume_plane *x_item = new Volume_plane(); - Volume_plane *y_item = new Volume_plane(); - Volume_plane *z_item = new Volume_plane(); + Volume_plane *x_item = new Volume_plane(img->image()->tx,img->image()->ty, img->image()->tz); + Volume_plane *y_item = new Volume_plane(img->image()->tx,img->image()->ty, img->image()->tz); + Volume_plane *z_item = new Volume_plane(img->image()->tx,img->image()->ty, img->image()->tz); x_item->setProperty("img",qVariantFromValue((void*)seg_img)); y_item->setProperty("img",qVariantFromValue((void*)seg_img)); @@ -682,7 +681,7 @@ private: x_item->setColor(QColor("red")); y_item->setColor(QColor("green")); z_item->setColor(QColor("blue")); - CGAL::Three::Viewer_interface* viewer = static_cast(QGLViewer::QGLViewerPool().first()); + CGAL::Three::Viewer_interface* viewer = static_cast(CGAL::QGLViewer::QGLViewerPool().first()); viewer->installEventFilter(x_item); viewer->installEventFilter(y_item); viewer->installEventFilter(z_item); @@ -755,7 +754,7 @@ private Q_SLOTS: msgBox.setText(QString("Planes created : %1/3").arg(nbPlanes)); if(nbPlanes == 3) { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); if(offset != first_offset) { for(int i=0; inumberOfEntries(); ++i) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp index 6fd110b52c3..83e6ad3f671 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp @@ -294,7 +294,7 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) else if (NULL != image_item) { item = image_item; - features_protection_available = (polylines_item != NULL) || !image_item->isGray(); + features_protection_available = true; bool fit_wrdtp = true; std::size_t img_wdim = image_item->image()->image()->wdim; @@ -462,7 +462,6 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults) ui.protectEdges->addItem(QString("Input polylines")); else { - CGAL_assertion(!image_item->isGray()); ui.protectEdges->addItem(QString("Polylines on cube")); } } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp index 333dc7862a0..2e67a7c18fc 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp @@ -19,6 +19,19 @@ using namespace CGAL::Three; typedef Tr::Bare_point Bare_point; +struct Compare_to_isovalue { + double iso_value; + bool less; + typedef bool result_type; + + Compare_to_isovalue(double iso_value, bool less) + : iso_value(iso_value), less(less) {} + + bool operator()(double x) const { + return (x < iso_value) == less; + } +}; + template struct Polyhedral_mesh_domain_selector { @@ -219,9 +232,12 @@ Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface* pfunction, pfunction->bbox().xmax(), pfunction->bbox().ymax(), pfunction->bbox().zmax()); - + namespace p = CGAL::parameters; Function_mesh_domain* p_domain = - new Function_mesh_domain(Function_wrapper(*pfunction), domain_bbox, 1e-7); + new Function_mesh_domain(Function_wrapper(*pfunction), domain_bbox, 1e-7, + p::construct_surface_patch_index = + [](int i, int j) { return (i * 1000 + j); } + ); Scene_c3t3_item* p_new_item = new Scene_c3t3_item; p_new_item->setScene(scene); @@ -246,10 +262,9 @@ Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface* pfunction, #ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES -#include +#include -typedef CGAL::Gray_image_mesh_domain_3 Gray_image_domain1; -typedef CGAL::Polyhedron_demo_labeled_mesh_domain_3 Gray_image_domain; +typedef CGAL::Labeled_mesh_domain_3 Gray_image_domain; typedef CGAL::Mesh_domain_with_polyline_features_3 Gray_Image_mesh_domain; Meshing_thread* cgal_code_mesh_3(const Image* pImage, @@ -271,21 +286,7 @@ Meshing_thread* cgal_code_mesh_3(const Image* pImage, { if (NULL == pImage) { return NULL; } - Image_mesh_domain* p_domain = new Image_mesh_domain(*pImage, 1e-6); - - if(protect_features && polylines.empty()) - { - std::vector > polylines_on_bbox; - if(pImage->image()->wordKind == WK_FLOAT) - CGAL::polylines_to_protect(*pImage, polylines_on_bbox); - else //WK_FIXED - CGAL::polylines_to_protect(*pImage, polylines_on_bbox); - - p_domain->add_features(polylines_on_bbox.begin(), polylines_on_bbox.end()); - } if(! polylines.empty()){ - // Insert edge in domain - p_domain->add_features(polylines.begin(), polylines.end()); protect_features = true; // so that it will be passed in make_mesh_3 } Mesh_parameters param; @@ -303,14 +304,30 @@ Meshing_thread* cgal_code_mesh_3(const Image* pImage, p_new_item->setScene(scene); if(!is_gray) { - Image_mesh_domain* p_domain = new Image_mesh_domain(*pImage, 1e-6); + namespace p = CGAL::parameters; + + Image_mesh_domain* p_domain = new Image_mesh_domain + (Image_mesh_domain::create_labeled_image_mesh_domain + (p::image = *pImage, + p::relative_error_bound = 1e-6, + p::construct_surface_patch_index = + [](int i, int j) { return (i * 1000 + j); } + ) + ); if(protect_features && polylines.empty()){ std::vector > polylines_on_bbox; - CGAL::polylines_to_protect< - Bare_point, - Image_mesh_domain::Image_word_type>(*pImage, polylines_on_bbox); - p_domain->add_features(polylines_on_bbox.begin(), polylines_on_bbox.end()); + + CGAL_IMAGE_IO_CASE(pImage->image(), + { + typedef Word Image_word_type; + (CGAL::polylines_to_protect< + Bare_point, + Image_word_type>(*pImage, polylines_on_bbox)); + p_domain->add_features(polylines_on_bbox.begin(), + polylines_on_bbox.end()); + } + ); } if(! polylines.empty()){ // Insert edge in domain @@ -324,20 +341,53 @@ Meshing_thread* cgal_code_mesh_3(const Image* pImage, } else { - if(CGAL::Compare_to_isovalue(iso_value, inside_is_less)(value_outside) !=0) + if(Compare_to_isovalue(iso_value, inside_is_less)(value_outside) !=0) { std::cerr << "Warning : \"Value inside is less than iso value\"'s value has been inverted to avoid crash. " << " " << std::endl; inside_is_less = !inside_is_less; } - Gray_Image_mesh_domain* p_domain = new Gray_Image_mesh_domain(*pImage, CGAL::Compare_to_isovalue(iso_value, inside_is_less), value_outside); + Compare_to_isovalue domain_functor(iso_value, inside_is_less); + namespace p = CGAL::parameters; + Gray_Image_mesh_domain* p_domain = new Gray_Image_mesh_domain + (Gray_Image_mesh_domain::create_gray_image_mesh_domain + (p::image = *pImage, + p::relative_error_bound = 1e-6, + p::image_values_to_subdomain_indices = domain_functor, + p::value_outside = value_outside, + p::construct_surface_patch_index = + [](int i, int j) { return (i * 1000 + j); } + ) + ); if(protect_features && polylines.empty()) { - std::cerr << "Warning : Automatic detection of features" - << " in Gray images is not implemented yet" << std::endl; - //std::vector > polylines_on_bbox; - //CGAL::polylines_to_protect(*pImage, polylines_on_bbox); - //p_domain->add_features(polylines_on_bbox.begin(), polylines_on_bbox.end()); + using CGAL::internal::Mesh_3::Linear_interpolator; + std::vector > polylines_on_bbox; + + CGAL_IMAGE_IO_CASE(pImage->image(), + + typedef Word Image_word_type; + (CGAL::polylines_to_protect + ( *pImage, + pImage->vx(), + pImage->vy(), + pImage->vz(), + polylines_on_bbox, + (Image_word_type*)0, + CGAL::Null_subdomain_index(), + domain_functor, + Linear_interpolator(), + 0, + 0, + Image_word_type(iso_value), + (std::max)(10, int(10 * (std::min)((std::min)(pImage->vx(), + pImage->vy()), + pImage->vz()) + / edge_size)))); + + ); + + p_domain->add_features(polylines_on_bbox.begin(), polylines_on_bbox.end()); } if(! polylines.empty()){ // Insert edge in domain diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h index 2ce3be3db6d..9db5fdb62de 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h @@ -218,12 +218,14 @@ initialize(const Mesh_criteria& criteria, Mesh_fnt::Labeled_image_domain_tag) // for a labeled image { if(p_.detect_connected_components) { - initialize_triangulation_from_labeled_image(c3t3_ - , *domain_ - , *p_.image_3_ptr - , criteria - , typename D_::Image_word_type() - , p_.protect_features); + CGAL_IMAGE_IO_CASE(p_.image_3_ptr->image(), + initialize_triangulation_from_labeled_image(c3t3_ + , *domain_ + , *p_.image_3_ptr + , criteria + , Word() + , p_.protect_features); + ); } else { initialize(criteria, Mesh_fnt::Domain_tag()); } @@ -361,7 +363,7 @@ tweak_criteria(Mesh_criteria& c, Mesh_fnt::Polyhedral_domain_tag) { typedef CGAL::Mesh_3::Facet_topological_criterion_with_adjacency New_topo_adj_crit; - if((int(c.facet_criteria().topology()) & + if((int(c.facet_criteria_object().topology()) & CGAL::FACET_VERTICES_ON_SAME_SURFACE_PATCH_WITH_ADJACENCY_CHECK) != 0) { c.add_facet_criterion(new New_topo_adj_crit(this->domain_)); diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin_cgal_code.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin_cgal_code.cpp index ae4d364facf..eb618fe9410 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin_cgal_code.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Optimization_plugin_cgal_code.cpp @@ -111,9 +111,14 @@ Optimizer_thread* cgal_code_optimization(Scene_c3t3_item& c3t3_item, { return NULL; } - - Image_mesh_domain* p_domain = new Image_mesh_domain(*p_image, 1e-6); - + + Image_mesh_domain* p_domain = + new Image_mesh_domain(Image_mesh_domain::create_labeled_image_mesh_domain + (CGAL::parameters::image = *p_image, + CGAL::parameters::relative_error_bound = 1e-6, + CGAL::parameters::construct_surface_patch_index = + [](int i, int j) { return (i * 1000 + j); } )); + // Create thread typedef Optimization_function Opt_function; Opt_function* p_opt_function = new Opt_function(p_result_item->c3t3(), p_domain, param); @@ -182,8 +187,10 @@ Optimizer_thread* cgal_code_optimization(Scene_c3t3_item& c3t3_item, p_function->bbox().zmax()); Function_mesh_domain* p_domain = - new Function_mesh_domain(Function_wrapper(*p_function), dom_bbox, 1e-7); - + new Function_mesh_domain(Function_wrapper(*p_function), dom_bbox, 1e-7, + CGAL::parameters::construct_surface_patch_index = + [](int i, int j) { return (i * 1000 + j); } ); + // Create thread typedef Optimization_function Opt_function; Opt_function* p_opt_function = new Opt_function(p_result_item->c3t3(), p_domain, param); diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Polyhedron_demo_mesh_3_labeled_mesh_domain_3.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Polyhedron_demo_mesh_3_labeled_mesh_domain_3.h deleted file mode 100644 index 062d68ee74a..00000000000 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Polyhedron_demo_mesh_3_labeled_mesh_domain_3.h +++ /dev/null @@ -1,291 +0,0 @@ -// Copyright (c) 2009 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// You can redistribute it and/or modify it under the terms of the GNU -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0+ -// -// -// Author(s) : Jane Tournois -// -//****************************************************************************** -// File Description : -// class Labeled_mesh_domain_3. See class description. -//****************************************************************************** - -#ifndef CGAL_POLYHEDRON_DEMO_LABELED_MESH_DOMAIN_3_H -#define CGAL_POLYHEDRON_DEMO_LABELED_MESH_DOMAIN_3_H - -#include -#include -#include "Image_type.h" - -#include - -namespace CGAL { - -struct Compare_to_isovalue { - float iso_value; - bool less; - - Compare_to_isovalue(float iso_value, bool less) - : iso_value(iso_value), less(less) {} - - bool operator()(float x) const { - return (x < iso_value) == less; - } -}; - -/** - * \class Polyhedron_demo_labeled_mesh_domain_3 - * LabeledDomain must be a Labeled_mesh_domain_3 - */ -template -class Polyhedron_demo_labeled_mesh_domain_3 - : public LabeledDomain -{ -public: - typedef LabeledDomain Base; - typedef Polyhedron_demo_labeled_mesh_domain_3 Domain; - - //------------------------------------------------------- - // Index Types - //------------------------------------------------------- - /// Type of indexes for cells of the input complex - typedef typename Base::Subdomain_index Subdomain_index; - typedef boost::optional Subdomain; - - /// Type of indexes for surface patch of the input complex - typedef int Surface_patch_index; - typedef boost::optional Surface_patch; - - typedef typename Base::Point_3 Point_3; - typedef typename Base::Segment_3 Segment_3; - - /// Type of indexes to characterize the lowest dimensional face of the input - /// complex on which a vertex lie - typedef int Index; - typedef CGAL::cpp11::tuple Intersection; - - //constructors - Polyhedron_demo_labeled_mesh_domain_3( - const typename Base::Fct& f, - const typename Base::Bbox_3& bbox, - const typename Base::FT& error_bound = Base::FT(1e-3), - CGAL::Random* p_rng = NULL) - : Base(f, bbox, error_bound, - // Subdomain_index(), Null_subdomain_index(), - p_rng) - {} - - Polyhedron_demo_labeled_mesh_domain_3( - const Image& img, - const typename Base::FT& error_bound = Base::FT(1e-3), - CGAL::Random* p_rng = NULL) - : Base(img, error_bound, - // Subdomain_index(), Null_subdomain_index(), - p_rng) - {} - - ///Constructor for the Gray-level Images - Polyhedron_demo_labeled_mesh_domain_3( - const Image& img, - const Compare_to_isovalue iso_value_transform, - const float value_outside) - : Base(img, iso_value_transform, value_outside) - {} - - /** - * Returns the index to be stored in a vertex lying on the surface identified - * by \c index. - */ - Index index_from_surface_patch_index( - const Surface_patch_index& index) const - { - return Index(index); - } - - Index index_from_surface_patch_index( - const typename Base::Surface_patch_index& index_pair) const - { - return Index(index_pair.first * 1000 + index_pair.second); - } - - Index index_from_surface_patch_index( - const typename Base::Index& index) const - { - return index_from_surface_patch_index(surface_patch_index(index)); - } - - Index index_from_index( - const typename Base::Index& index) const - { - if (const typename Base::Surface_patch_index* index_pair = - boost::get(&index)) - return Index(index_pair->first * 1000 + index_pair->second); - - else if (const typename Base::Subdomain_index* sub_index = - boost::get(&index)) - return Index(*sub_index); - - return Index(-1);//~error - } - - /** - * Returns the index to be stored in a vertex lying in the subdomain - * identified by \c index. - */ - Index index_from_subdomain_index(const Subdomain_index& index) const - { return Index(index); } - - /** - * Returns the \c Surface_patch_index of the surface patch - * where lies a vertex with dimension 2 and index \c index. - */ - Surface_patch_index - surface_patch_index(const Index& index) const - { - return index; - } - - Surface_patch_index - surface_patch_index(const typename Base::Index& index) const - { - typename Base::Surface_patch_index index_pair = - boost::get(index); - return Surface_patch_index(index_pair.first * 1000 + index_pair.second); - } - - typename Base::Surface_patch_index - surface_patch_index_base(const Index& index) const - { - return typename Base::Surface_patch_index(index / 1000, - index % 1000); - } - - /** - * Returns the index of the subdomain containing a vertex - * with dimension 3 and index \c index. - */ - Subdomain_index subdomain_index(const Index& index) const - { return index; } - - // ----------------------------------- - // Backward Compatibility - // ----------------------------------- -#ifndef CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX - typedef Surface_patch_index Surface_index; - - Index index_from_surface_index(const Surface_index& index) const - { return index_from_surface_patch_index(index); } - - Surface_index surface_index(const Index& index) const - { return surface_patch_index(index); } -#endif // CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX - // ----------------------------------- - // End backward Compatibility - // ----------------------------------- - - - struct Construct_initial_points - { - Construct_initial_points(const Domain& domain) - : r_domain_(domain) {} - - template - OutputIterator operator()(OutputIterator pts, const int n = 12) const - { - typename Base::Construct_initial_points cip = - r_domain_.Base::construct_initial_points_object(); - - std::vector > initial_points; - cip(std::back_inserter(initial_points), n); - - for (std::size_t i = 0; i < initial_points.size(); ++i) - { - std::pair p = initial_points[i]; - *pts++ = std::make_pair(p.first, - r_domain_.surface_patch_index(p.second)); - } - return pts; - } - - private: - const Domain& r_domain_; - }; - - /// Returns Construct_initial_points object - Construct_initial_points construct_initial_points_object() const - { - return Construct_initial_points(*this); - } - - - struct Construct_intersection - { - Construct_intersection(const Domain& domain) - : r_domain_(domain) {} - - template - Intersection operator()(const Query& q) const - { - typename Base::Construct_intersection - ci = r_domain_.Base::construct_intersection_object(); - typename Base::Intersection bi = ci(q); - - return CGAL::cpp11::make_tuple( - CGAL::cpp11::get<0>(bi), - r_domain_.index_from_index(CGAL::cpp11::get<1>(bi)), - CGAL::cpp11::get<2>(bi)); - } - - private: - const Domain& r_domain_; - }; - - /// Returns Construct_intersection object - Construct_intersection construct_intersection_object() const - { - return Construct_intersection(*this); - } - - -private: - ///// Returns Surface_patch_index from \c i and \c j - //typename Base::Surface_patch_index - // make_surface_index(const Subdomain_index i, - // const Subdomain_index j) const - //{ - // if ( i < j ) - // return typename Base::Surface_patch_index(i, j); - // else - // return typename Base::Surface_patch_index(j, i); - //} - - Surface_patch_index - make_surface_index(const Subdomain_index i, - const Subdomain_index j) const - { - if (i < j) - return (i * 1000 + j); - else - return (j * 1000 + i); - } - -}; // end class Labeled_mesh_domain_3 - -} // end namespace CGAL - -#endif // CGAL_POLYHEDRON_DEMO_LABELED_MESH_DOMAIN_3_H - diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane.h index b5c5ada6b78..a0bf54f9488 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane.h @@ -7,7 +7,7 @@ #include #include -#include +#include #include "Volume_plane_interface.h" #include "create_sphere.h" @@ -16,6 +16,7 @@ #include #include #include +#include #include using namespace CGAL::Three; @@ -32,14 +33,14 @@ void printGlError(CGAL::Three::Viewer_interface*, unsigned int) { #endif template -class Length_constraint : public qglviewer::WorldConstraint { +class Length_constraint : public CGAL::qglviewer::WorldConstraint { public: Length_constraint(double max_) : max_(max_) { } - void constrainTranslation(qglviewer::Vec& t, qglviewer::Frame* const frame) { + void constrainTranslation(CGAL::qglviewer::Vec& t, CGAL::qglviewer::Frame* const frame) { WorldConstraint::constrainTranslation(t, frame); - qglviewer::Vec pos = frame->position(); - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + CGAL::qglviewer::Vec pos = frame->position(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); double start = pos[Dim] - offset[Dim]; double end = t[Dim]; start += end; @@ -58,12 +59,14 @@ struct z_tag {}; template class Volume_plane : public Volume_plane_interface, public Tag { +private : + float tx, ty, tz; public: - Volume_plane(); + Volume_plane(float tx, float ty, float tz); void invalidateOpenGLBuffers() { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); mFrame_->setPosition(offset.x, offset.y, offset.z); } bool eventFilter(QObject *, QEvent *); @@ -74,20 +77,20 @@ public: void compute_bbox(x_tag)const { - _bbox = Bbox(0,0,0, - 0, (adim_ - 1) * yscale_, (bdim_ - 1) * zscale_); + _bbox = Bbox(tx,ty,tz, + tx, ty+(adim_ - 1) * yscale_, tz+(bdim_ - 1) * zscale_); } void compute_bbox(y_tag)const { - _bbox = Bbox(0,0,0, - (adim_ - 1) * xscale_, 0, (bdim_ - 1) * zscale_); + _bbox = Bbox(tx,ty,tz, + tx+(adim_ - 1) * xscale_, ty, tz+(bdim_ - 1) * zscale_); } void compute_bbox(z_tag)const { - _bbox = Bbox(0,0,0, - (adim_ - 1) * xscale_, (bdim_ - 1) * yscale_, 0); + _bbox = Bbox(tx,ty,tz, + tx+(adim_ - 1) * xscale_,ty+ (bdim_ - 1) * yscale_, tz); } void setData(unsigned int adim, unsigned int bdim, unsigned int cdim, @@ -115,7 +118,7 @@ public: unsigned int bDim() const { return bdim_; } unsigned int cDim() const { return cdim_; } - qglviewer::Vec translationVector() const { return translationVector(*this); } + CGAL::qglviewer::Vec translationVector() const { return translationVector(*this); } unsigned int getCurrentCube() const { return currentCube; } @@ -137,14 +140,14 @@ private: static const char* fragmentShader_bordures_source; - qglviewer::Vec translationVector(x_tag) const { - return qglviewer::Vec(xscale_, 0.0, 0.0); + CGAL::qglviewer::Vec translationVector(x_tag) const { + return CGAL::qglviewer::Vec(xscale_, 0.0, 0.0); } - qglviewer::Vec translationVector(y_tag) const { - return qglviewer::Vec(0.0, yscale_, 0.0); + CGAL::qglviewer::Vec translationVector(y_tag) const { + return CGAL::qglviewer::Vec(0.0, yscale_, 0.0); } - qglviewer::Vec translationVector(z_tag) const { - return qglviewer::Vec(0.0, 0.0, zscale_); + CGAL::qglviewer::Vec translationVector(z_tag) const { + return CGAL::qglviewer::Vec(0.0, 0.0, zscale_); } void initShaders(); @@ -266,24 +269,24 @@ private: 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); } - qglviewer::Constraint* setConstraint(x_tag) { - qglviewer::AxisPlaneConstraint* c = new Length_constraint<0>(cdim_ * xscale_); - c->setRotationConstraintType(qglviewer::AxisPlaneConstraint::FORBIDDEN); - c->setTranslationConstraint(qglviewer::AxisPlaneConstraint::AXIS, qglviewer::Vec(1.0f, 0.0f, 0.0f)); + CGAL::qglviewer::Constraint* setConstraint(x_tag) { + CGAL::qglviewer::AxisPlaneConstraint* c = new Length_constraint<0>(cdim_ * xscale_); + c->setRotationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FORBIDDEN); + c->setTranslationConstraint(CGAL::qglviewer::AxisPlaneConstraint::AXIS, CGAL::qglviewer::Vec(1.0f, 0.0f, 0.0f)); return c; } - qglviewer::Constraint* setConstraint(y_tag) { - qglviewer::AxisPlaneConstraint* c = new Length_constraint<1>(cdim_ * yscale_); - c->setRotationConstraintType(qglviewer::AxisPlaneConstraint::FORBIDDEN); - c->setTranslationConstraint(qglviewer::AxisPlaneConstraint::AXIS, qglviewer::Vec(0.0f, 1.0f, 0.0f)); + CGAL::qglviewer::Constraint* setConstraint(y_tag) { + CGAL::qglviewer::AxisPlaneConstraint* c = new Length_constraint<1>(cdim_ * yscale_); + c->setRotationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FORBIDDEN); + c->setTranslationConstraint(CGAL::qglviewer::AxisPlaneConstraint::AXIS, CGAL::qglviewer::Vec(0.0f, 1.0f, 0.0f)); return c; } - qglviewer::Constraint* setConstraint(z_tag) { - qglviewer::AxisPlaneConstraint* c = new Length_constraint<2>(cdim_ * zscale_); - c->setRotationConstraintType(qglviewer::AxisPlaneConstraint::FORBIDDEN); - c->setTranslationConstraint(qglviewer::AxisPlaneConstraint::AXIS, qglviewer::Vec(0.0f, 0.0f, 1.0f)); + CGAL::qglviewer::Constraint* setConstraint(z_tag) { + CGAL::qglviewer::AxisPlaneConstraint* c = new Length_constraint<2>(cdim_ * zscale_); + c->setRotationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FORBIDDEN); + c->setTranslationConstraint(CGAL::qglviewer::AxisPlaneConstraint::AXIS, CGAL::qglviewer::Vec(0.0f, 0.0f, 1.0f)); return c; } @@ -294,15 +297,15 @@ private: GLdouble getTranslation() const { return getTranslation(*this); } GLdouble getTranslation(x_tag) const { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); return (mFrame_->matrix()[12] - offset.x)/ xscale_; } GLdouble getTranslation(y_tag) const { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); return (mFrame_->matrix()[13] - offset.y)/ yscale_; } GLdouble getTranslation(z_tag) const { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); return (mFrame_->matrix()[14] - offset.z)/ zscale_ ; } @@ -379,10 +382,11 @@ const char* Volume_plane::fragmentShader_bordures_source = template -Volume_plane::Volume_plane() - : Volume_plane_interface(new qglviewer::ManipulatedFrame) +Volume_plane::Volume_plane(float tx, float ty, float tz) + : Volume_plane_interface(new CGAL::qglviewer::ManipulatedFrame), + tx(tx), ty(ty), tz(tz) { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); mFrame_->setPosition(offset.x, offset.y, offset.z); sphere_Slider = new QSlider(Qt::Horizontal); sphere_Slider->setValue(40); @@ -431,6 +435,7 @@ void Volume_plane::draw(Viewer_interface *viewer) const { mvp.data()[i] = (float)mat[i]; f.data()[i] = (float)mFrame_->matrix()[i]; } + mvp.translate(QVector3D(tx, ty, tz)); program_bordures.bind(); @@ -472,7 +477,7 @@ void Volume_plane::draw(Viewer_interface *viewer) const { cbuffer.bind(); int colorLoc = program.attributeLocation("color"); program.enableAttributeArray(colorLoc); - program.setAttributeBuffer(colorLoc, GL_FLOAT, (currentCube*sizeof(float)) * (bdim_) * (adim_), 1, 0 ); + program.setAttributeBuffer(colorLoc, GL_FLOAT, (currentCube*int(sizeof(float))) * (bdim_) * (adim_), 1, 0 ); cbuffer.release(); @@ -578,7 +583,10 @@ void Volume_plane::init(Viewer_interface* viewer) { for(unsigned int i = 0; i < indices.size(); i+=slice) { QOpenGLBuffer ebo = QOpenGLBuffer(QOpenGLBuffer::IndexBuffer); - unsigned int left_over = (i + slice) > indices.size() ? std::distance(indices.begin() + i, indices.end()) : slice; + unsigned int left_over = + (i + slice) > indices.size() ? + (unsigned int)(std::distance(indices.begin() + i, indices.end())) : + slice; ebo.create(); ebo.bind(); ebo.allocate(&indices[i],static_cast(sizeof(unsigned int) * left_over)); @@ -621,7 +629,7 @@ void Volume_plane::initShaders() { template bool Volume_plane::eventFilter(QObject *, QEvent *event) { - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); if(event->type() == QEvent::MouseButtonPress) { QMouseEvent* e = static_cast(event); @@ -630,18 +638,18 @@ bool Volume_plane::eventFilter(QObject *, QEvent *event) //pick bool found = false; viewer->makeCurrent(); - qglviewer::Vec pos = viewer->camera()->pointUnderPixel(e->pos(), found); + CGAL::qglviewer::Vec pos = viewer->camera()->pointUnderPixel(e->pos(), found); if(!found) return false; found = false; //check the found point is on a sphere pos = manipulatedFrame()->inverse().inverseCoordinatesOf(pos); float sq_radius = sphere_radius * sphere_radius; - qglviewer::Vec center; + CGAL::qglviewer::Vec center; //is the picked point on the sphere ? for (int i=0; i<4; ++i) { - center = qglviewer::Vec(c_spheres[i*3], c_spheres[i*3+1], c_spheres[i*3+2]); + center = CGAL::qglviewer::Vec(c_spheres[i*3]+tx, c_spheres[i*3+1]+ty, c_spheres[i*3+2]+tz); if( (center.x - pos.x) * (center.x - pos.x) + (center.y - pos.y) * (center.y - pos.y) + @@ -660,8 +668,8 @@ bool Volume_plane::eventFilter(QObject *, QEvent *event) viewer->setMouseBinding( Qt::NoModifier, Qt::LeftButton, - QGLViewer::FRAME, - QGLViewer::TRANSLATE); + CGAL::qglviewer::FRAME, + CGAL::qglviewer::TRANSLATE); } } else if(event->type() == QEvent::MouseButtonRelease && is_grabbing) @@ -670,8 +678,8 @@ bool Volume_plane::eventFilter(QObject *, QEvent *event) viewer->setMouseBinding( Qt::NoModifier, Qt::LeftButton, - QGLViewer::CAMERA, - QGLViewer::ROTATE); + CGAL::qglviewer::CAMERA, + CGAL::qglviewer::ROTATE); } return false; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_interface.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_interface.h index 088c587b0a4..c579364101a 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_interface.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_interface.h @@ -6,16 +6,16 @@ #include #include #include -#include +#include #include #include #include -#include +#include using namespace CGAL::Three; class Volume_plane_interface : public Scene_item { Q_OBJECT public: - Volume_plane_interface(qglviewer::ManipulatedFrame* f) : mFrame_(f) { + Volume_plane_interface(CGAL::qglviewer::ManipulatedFrame* f) : mFrame_(f) { connect(mFrame_, SIGNAL(manipulated()), this, SLOT(propagateManipulation())); } @@ -29,7 +29,7 @@ public: virtual unsigned int aDim() const = 0; virtual unsigned int bDim() const = 0; virtual unsigned int cDim() const = 0; - virtual qglviewer::Vec translationVector() const = 0; + virtual CGAL::qglviewer::Vec translationVector() const = 0; void itemAboutToBeDestroyed(CGAL::Three::Scene_item* item) { if(this == item) { Q_EMIT planeDestructionIncoming(this); @@ -40,7 +40,7 @@ public: virtual unsigned int getCurrentCube() const = 0; void emitSelection() { Q_EMIT selected(this); } - virtual qglviewer::ManipulatedFrame* manipulatedFrame() { return mFrame_; } + virtual CGAL::qglviewer::ManipulatedFrame* manipulatedFrame() { return mFrame_; } QMenu* contextMenu() { @@ -74,7 +74,7 @@ private Q_SLOTS: Q_EMIT manipulated(getCurrentCube()); } protected: - qglviewer::ManipulatedFrame* mFrame_; + CGAL::qglviewer::ManipulatedFrame* mFrame_; bool hide_spheres; QSlider* sphere_Slider; }; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_intersection.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_intersection.cpp index 300113f1f31..d48b46f3663 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_intersection.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_intersection.cpp @@ -6,13 +6,16 @@ #include struct Volume_plane_intersection_priv { - Volume_plane_intersection_priv(float x, float y, float z, Volume_plane_intersection* parent) - : a(NULL), b(NULL), c(NULL), x(x), y(y), z(z) , item(parent) + Volume_plane_intersection_priv(float x, float y, float z, + float tx, float ty, float tz, + Volume_plane_intersection* parent) + : a(NULL), b(NULL), c(NULL), x(x), y(y), z(z), + tx(tx), ty(ty), tz(tz), item(parent) { item->are_buffers_filled = false; } Volume_plane_interface *a, *b, *c; - float x, y, z; + float x, y, z, tx, ty, tz; enum VAOs{ AArray = 0, @@ -48,31 +51,31 @@ void Volume_plane_intersection_priv::computeElements() a_vertex.resize(0); b_vertex.resize(0); c_vertex.resize(0); - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); - a_vertex.push_back(0.0-offset.x); - a_vertex.push_back(0.0-offset.y); - a_vertex.push_back(0.0-offset.z); - a_vertex.push_back(x -offset.x); - a_vertex.push_back(0.0-offset.y); - a_vertex.push_back(0.0-offset.z); + a_vertex.push_back(0.0-offset.x+tx); + a_vertex.push_back(0.0-offset.y+ty); + a_vertex.push_back(0.0-offset.z+tz); + a_vertex.push_back(x -offset.x+tx); + a_vertex.push_back(0.0-offset.y+ty); + a_vertex.push_back(0.0-offset.z+tz); - b_vertex.push_back(0.0-offset.x); - b_vertex.push_back(0.0-offset.y); - b_vertex.push_back(0.0-offset.z); - b_vertex.push_back(0.0-offset.x); - b_vertex.push_back(y -offset.y); - b_vertex.push_back(0.0-offset.z); + b_vertex.push_back(0.0-offset.x+tx); + b_vertex.push_back(0.0-offset.y+ty); + b_vertex.push_back(0.0-offset.z+tz); + b_vertex.push_back(0.0-offset.x+tx); + b_vertex.push_back(y -offset.y+ty); + b_vertex.push_back(0.0-offset.z+tz); - c_vertex.push_back(0.0-offset.x); - c_vertex.push_back(0.0-offset.y); - c_vertex.push_back(0.0-offset.z); - c_vertex.push_back(0.0-offset.x); - c_vertex.push_back(0.0-offset.y); - c_vertex.push_back(z -offset.z); + c_vertex.push_back(0.0-offset.x+tx); + c_vertex.push_back(0.0-offset.y+ty); + c_vertex.push_back(0.0-offset.z+tz); + c_vertex.push_back(0.0-offset.x+tx); + c_vertex.push_back(0.0-offset.y+ty); + c_vertex.push_back(z -offset.z+tz); - item->_bbox = Scene_item::Bbox( 0, 0, 0, - x, y, z); + item->_bbox = Scene_item::Bbox( tx, ty, tz, + tz+x, ty+y, tz+z); QApplication::restoreOverrideCursor(); } @@ -188,9 +191,10 @@ void Volume_plane_intersection::draw(Viewer_interface* viewer) const { viewer->glDepthRange(0.00001,1.0); } -Volume_plane_intersection::Volume_plane_intersection(float x, float y, float z) +Volume_plane_intersection::Volume_plane_intersection(float x, float y, float z, + float tx, float ty, float tz) :Scene_item(Volume_plane_intersection_priv::NumberOfVbos, Volume_plane_intersection_priv::NumberOfVaos), - d(new Volume_plane_intersection_priv(x,y,z,this)) + d(new Volume_plane_intersection_priv(x,y,z,tx,ty,tz,this)) { setColor(QColor(255, 128, 0)); setName("Volume plane intersection"); diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_intersection.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_intersection.h index 182d7f843e7..d258a4892af 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_intersection.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_intersection.h @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include #include @@ -18,7 +18,7 @@ class Volume_plane_intersection typedef std::pair Interface_pair; Q_OBJECT public: - Volume_plane_intersection(float x, float y, float z); + Volume_plane_intersection(float x, float y, float z, float tx, float ty, float tz); ~Volume_plane_intersection(); bool isFinite() const { return true; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_thread.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_thread.h index 5c3c14e4d3a..97a336f9b61 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_thread.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_thread.h @@ -78,7 +78,8 @@ void X_plane_thread::run() { for(unsigned int i = 0; i < img->xdim(); ++i) { for(unsigned int j = 0; j < img->ydim(); ++j) { for(unsigned int k = 0; k < img->zdim(); ++k) { - float x = CGAL::IMAGEIO::static_evaluate(img->image(), i, j, k); + float x = float(CGAL::IMAGEIO::static_evaluate(img->image(), + i, j, k)); x = clamper(x); buffer.push_back(x); } @@ -98,7 +99,8 @@ void Y_plane_thread::run() { for(unsigned int i = 0; i < img->ydim(); ++i) { for(unsigned int j = 0; j < img->xdim(); ++j) { for(unsigned int k = 0; k < img->zdim(); ++k) { - float x = CGAL::IMAGEIO::static_evaluate(img->image(), j, i, k); + float x = float(CGAL::IMAGEIO::static_evaluate(img->image(), + j, i, k)); x = clamper(x); buffer.push_back(x); } @@ -116,7 +118,8 @@ void Z_plane_thread::run() { for(unsigned int i = 0; i < img->zdim(); ++i) { for(unsigned int j = 0; j < img->xdim(); ++j) { for(unsigned int k = 0; k < img->ydim(); ++k) { - float x = CGAL::IMAGEIO::static_evaluate(img->image(), j, k, i); + float x = float(CGAL::IMAGEIO::static_evaluate(img->image(), + j, k, i)); x = clamper(x); buffer.push_back(x); } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Clip_polyhedron_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Clip_polyhedron_plugin.cpp index 5488aea73c6..ba3ef64caec 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Clip_polyhedron_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Operations_on_polyhedra/Clip_polyhedron_plugin.cpp @@ -202,7 +202,7 @@ public Q_SLOTS: else { QApplication::setOverrideCursor(Qt::WaitCursor); - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); QList polyhedra; //Fills the list of target polyhedra and the cutting plane diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Affine_transform_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Affine_transform_plugin.cpp index fbf7f20c7c7..b6e0a942670 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Affine_transform_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Affine_transform_plugin.cpp @@ -36,13 +36,13 @@ class Scene_transform_point_set_item : public Scene_item Q_OBJECT typedef Point_set_3 Point_set; public: - Scene_transform_point_set_item(Scene_points_with_normal_item *item, const qglviewer::Vec& pos) + Scene_transform_point_set_item(Scene_points_with_normal_item *item, const CGAL::qglviewer::Vec& pos) :Scene_item(1,1), base(item), center_(pos), frame(new CGAL::Three::Scene_item::ManipulatedFrame()) { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); frame->setPosition(pos+offset); Point_set ps= *item->point_set(); const Kernel::Point_3& p = ps.point(*(ps.begin())); @@ -61,7 +61,7 @@ public: _bbox = Bbox(bbox.xmin(),bbox.ymin(),bbox.zmin(), bbox.xmax(),bbox.ymax(),bbox.zmax()); nb_points = points.size(); - CGAL::Three::Viewer_interface* viewer = static_cast(*QGLViewer::QGLViewerPool().begin()); + CGAL::Three::Viewer_interface* viewer = static_cast(*CGAL::QGLViewer::QGLViewerPool().begin()); program = getShaderProgram(Scene_facegraph_transform_item::PROGRAM_WITHOUT_LIGHT, viewer); program->bind(); @@ -127,7 +127,7 @@ public: return false; } const Scene_points_with_normal_item* getBase()const{return base;} - const qglviewer::Vec& center() const { return center_; } + const CGAL::qglviewer::Vec& center() const { return center_; } CGAL::Three::Scene_item::ManipulatedFrame* manipulatedFrame() { return frame; } void compute_bbox() const { @@ -139,8 +139,8 @@ public: { bbox = bbox + ps.point(*it).bbox(); } - qglviewer::Vec min(bbox.xmin(),bbox.ymin(),bbox.zmin()); - qglviewer::Vec max(bbox.xmax(),bbox.ymax(),bbox.zmax()); + CGAL::qglviewer::Vec min(bbox.xmin(),bbox.ymin(),bbox.zmin()); + CGAL::qglviewer::Vec max(bbox.xmax(),bbox.ymax(),bbox.zmax()); _bbox = Bbox(min.x,min.y,min.z, max.x,max.y,max.z); @@ -151,7 +151,7 @@ Q_SIGNALS: void killed(); private: const Scene_points_with_normal_item* base; - qglviewer::Vec center_; + CGAL::qglviewer::Vec center_; CGAL::Three::Scene_item::ManipulatedFrame* frame; mutable QOpenGLShaderProgram *program; std::size_t nb_points; @@ -336,14 +336,14 @@ public Q_SLOTS: if(!is_point_set) { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); transform_item->manipulatedFrame()->setFromMatrix(matrix); transform_item->manipulatedFrame()->translate(offset); transform_item->itemChanged(); } else { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); transform_points_item->manipulatedFrame()->setFromMatrix(matrix); transform_points_item->manipulatedFrame()->translate(offset); transform_points_item->itemChanged(); @@ -434,7 +434,7 @@ void Polyhedron_demo_affine_transform_plugin::start(FaceGraph *facegraph, const lastMatrix.data()[12] = x; lastMatrix.data()[13] = y; lastMatrix.data()[14] = z; - transform_item = new Scene_facegraph_transform_item(qglviewer::Vec(x,y,z),facegraph, name); + transform_item = new Scene_facegraph_transform_item(CGAL::qglviewer::Vec(x,y,z),facegraph, name); transform_item->setManipulatable(true); transform_item->setColor(Qt::green); transform_item->setRenderingMode(Wireframe); @@ -444,7 +444,7 @@ void Polyhedron_demo_affine_transform_plugin::start(FaceGraph *facegraph, const scaling[2] = 1; connect(transform_item, SIGNAL(stop()),this, SLOT(go())); connect(transform_item, SIGNAL(killed()),this, SLOT(transformed_killed())); - connect(transform_item->manipulatedFrame(), &qglviewer::ManipulatedFrame::modified, + connect(transform_item->manipulatedFrame(), &CGAL::qglviewer::ManipulatedFrame::modified, this, &Polyhedron_demo_affine_transform_plugin::updateUiMatrix); connect(transform_item, &Scene_facegraph_transform_item::aboutToBeDestroyed, dock_widget, &QDockWidget::hide); @@ -467,12 +467,12 @@ void Polyhedron_demo_affine_transform_plugin::start(Scene_points_with_normal_ite lastMatrix.data()[13] = y; lastMatrix.data()[14] = z; - transform_points_item = new Scene_transform_point_set_item(points_item,qglviewer::Vec(x,y,z)); + transform_points_item = new Scene_transform_point_set_item(points_item,CGAL::qglviewer::Vec(x,y,z)); transform_points_item->setRenderingMode(Points); transform_points_item->setName(tr("Affine Transformation")); connect(transform_points_item, SIGNAL(stop()),this, SLOT(go())); connect(transform_points_item, SIGNAL(killed()),this, SLOT(transformed_killed())); - connect(transform_points_item->manipulatedFrame(), &qglviewer::ManipulatedFrame::modified, + connect(transform_points_item->manipulatedFrame(), &CGAL::qglviewer::ManipulatedFrame::modified, this, &Polyhedron_demo_affine_transform_plugin::updateUiMatrix); connect(transform_points_item, &Scene_transform_point_set_item::aboutToBeDestroyed, dock_widget, &QDockWidget::hide); @@ -488,7 +488,7 @@ void Polyhedron_demo_affine_transform_plugin::end(){ QApplication::restoreOverrideCursor(); double matrix[16]; transformMatrix(&matrix[0]); - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); matrix[12]-=offset.x; matrix[13]-=offset.y; matrix[14]-=offset.z; @@ -499,7 +499,7 @@ void Polyhedron_demo_affine_transform_plugin::end(){ if(transform_item) { - qglviewer::Vec c = transform_item->center(); + CGAL::qglviewer::Vec c = transform_item->center(); FaceGraph* new_sm = new FaceGraph(*transform_item->getFaceGraph()); typedef boost::property_map::type VPmap; VPmap vpmap = get(CGAL::vertex_point, *new_sm); @@ -525,7 +525,7 @@ void Polyhedron_demo_affine_transform_plugin::end(){ const Point_set *base_ps = transform_points_item->getBase()->point_set(); Point_set* new_ps = new Point_set(); new_ps->reserve(base_ps->size()); - qglviewer::Vec c = transform_points_item->center(); + CGAL::qglviewer::Vec c = transform_points_item->center(); for(Point_set::const_iterator it = base_ps->begin(); it != base_ps->end(); ++ it) { QVector3D vec = transform_matrix * QVector3D(base_ps->point(*it).x() - c.x, @@ -580,7 +580,7 @@ void Polyhedron_demo_affine_transform_plugin::updateUiMatrix() matrix(1,3) -= transform_points_item->center().y; matrix(2,3) -= transform_points_item->center().z; } - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); matrix.data()[12]-=offset.x; matrix.data()[13]-=offset.y; matrix.data()[14]-=offset.z; @@ -675,25 +675,25 @@ void Polyhedron_demo_affine_transform_plugin::applySingleTransformation() //rotation case 0: { - qglviewer::Vec axis(ui.lineEditX->text().toDouble(), + CGAL::qglviewer::Vec axis(ui.lineEditX->text().toDouble(), ui.lineEditY->text().toDouble(), ui.lineEditZ->text().toDouble()); if(!is_point_set) - transform_item->manipulatedFrame()->rotate(qglviewer::Quaternion(axis, ui.lineEditA->text().toDouble()*M_PI/180.0)); + transform_item->manipulatedFrame()->rotate(CGAL::qglviewer::Quaternion(axis, ui.lineEditA->text().toDouble()*CGAL_PI/180.0)); else - transform_points_item->manipulatedFrame()->rotate(qglviewer::Quaternion(axis, ui.lineEditA->text().toDouble()*M_PI/180.0)); + transform_points_item->manipulatedFrame()->rotate(CGAL::qglviewer::Quaternion(axis, ui.lineEditA->text().toDouble()*CGAL_PI/180.0)); break; } //translation case 1: { if(!is_point_set) - transform_item->manipulatedFrame()->translate(qglviewer::Vec(ui.lineEditX->text().toDouble() , + transform_item->manipulatedFrame()->translate(CGAL::qglviewer::Vec(ui.lineEditX->text().toDouble() , ui.lineEditY->text().toDouble() , ui.lineEditZ->text().toDouble() )); else - transform_points_item->manipulatedFrame()->translate(qglviewer::Vec(ui.lineEditX->text().toDouble() , + transform_points_item->manipulatedFrame()->translate(CGAL::qglviewer::Vec(ui.lineEditX->text().toDouble() , ui.lineEditY->text().toDouble() , ui.lineEditZ->text().toDouble() )); break; diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp index 3b4933e54cf..c3b3f4f15ef 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Basic_generator_plugin.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Clipping_box_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Clipping_box_plugin.cpp index d1b7e6f5e7e..4dde5cd50e2 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Clipping_box_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Clipping_box_plugin.cpp @@ -96,7 +96,7 @@ dock_widget->show(); }); item->setName("Clipping box"); item->setRenderingMode(FlatPlusEdges); - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); viewer->installEventFilter(item); scene->addItem(item); actionClipbox->setEnabled(false); @@ -113,7 +113,7 @@ void Clipping_box_plugin::clip(bool b) { typedef CGAL::Epick Kernel; typedef CGAL::Polyhedron_3 Mesh; - Viewer_interface* viewer = static_cast(*QGLViewer::QGLViewerPool().begin()); + Viewer_interface* viewer = static_cast(*CGAL::QGLViewer::QGLViewerPool().begin()); if(b) { if(!item) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Edit_box_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Edit_box_plugin.cpp index c69a44d5243..bee21b495b2 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Edit_box_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Edit_box_plugin.cpp @@ -86,7 +86,7 @@ void Edit_box_plugin::bbox() this, SLOT(enableAction())); item->setName("Edit box"); item->setRenderingMode(FlatPlusEdges); - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); viewer->installEventFilter(item); scene->addItem(item); actionBbox->setEnabled(false); @@ -101,7 +101,7 @@ void Edit_box_plugin::enableAction() { void Edit_box_plugin::exportToPoly() { int id =0; - const qglviewer::Vec v_offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec v_offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); Kernel::Vector_3 offset(v_offset.x, v_offset.y, v_offset.z); Scene_edit_box_item* item = NULL; for(int i = 0, end = scene->numberOfEntries(); diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp index 320805968e3..61dcd92ebfc 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp @@ -1,7 +1,8 @@ #include "Scene_edit_box_item.h" #include #include -#include +#include +#include #include #include #include @@ -78,7 +79,7 @@ struct Scene_edit_box_item_priv{ Scene_edit_box_item_priv(const Scene_interface *scene_interface, Scene_edit_box_item* ebi) { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); ready_to_hl = true; scene = scene_interface; item = ebi; @@ -87,16 +88,16 @@ struct Scene_edit_box_item_priv{ double x=(bb.xmin()+bb.xmax())/2; double y=(bb.ymin()+bb.ymax())/2; double z=(bb.zmin()+bb.zmax())/2; - center_ = qglviewer::Vec(x,y,z); - relative_center_ = qglviewer::Vec(0,0,0); + center_ = CGAL::qglviewer::Vec(x,y,z); + relative_center_ = CGAL::qglviewer::Vec(0,0,0); remodel_frame = new Scene_item::ManipulatedFrame(); remodel_frame->setTranslationSensitivity(1.0); frame = new Scene_item::ManipulatedFrame(); frame->setPosition(center_+offset); frame->setSpinningSensitivity(100.0); //forbid spinning - constraint.setRotationConstraintType(qglviewer::AxisPlaneConstraint::AXIS); - constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::FREE); - constraint.setRotationConstraintDirection(qglviewer::Vec(.0,.0,.1)); + constraint.setRotationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::AXIS); + constraint.setTranslationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FREE); + constraint.setRotationConstraintDirection(CGAL::qglviewer::Vec(.0,.0,.1)); frame->setConstraint(&constraint); //create the sphere model pool[0] = bb.xmin(); pool[3] = bb.xmax(); @@ -298,12 +299,12 @@ struct Scene_edit_box_item_priv{ bool ready_to_hl; - qglviewer::ManipulatedFrame* frame; - qglviewer::ManipulatedFrame* remodel_frame; - qglviewer::Vec rf_last_pos; - qglviewer::LocalConstraint constraint; - qglviewer::Vec center_; - qglviewer::Vec relative_center_; + CGAL::qglviewer::ManipulatedFrame* frame; + CGAL::qglviewer::ManipulatedFrame* remodel_frame; + CGAL::qglviewer::Vec rf_last_pos; + CGAL::qglviewer::LocalConstraint constraint; + CGAL::qglviewer::Vec center_; + CGAL::qglviewer::Vec relative_center_; mutable QOpenGLShaderProgram pick_sphere_program; mutable QOpenGLShaderProgram transparent_face_program; @@ -346,7 +347,7 @@ Scene_edit_box_item::Scene_edit_box_item(const Scene_interface *scene_interface) d = new Scene_edit_box_item_priv(scene_interface, this); are_buffers_filled = false; - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); viewer->setMouseTracking(true); } QString Scene_edit_box_item::toolTip() const { @@ -438,7 +439,7 @@ void Scene_edit_box_item::drawEdges(Viewer_interface* viewer) const void Scene_edit_box_item::compute_bbox() const { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); QVector3D min(d->pool[0], d->pool[1], d->pool[2]); @@ -605,7 +606,7 @@ Scene_edit_box_item_priv::initializeBuffers(Viewer_interface *viewer)const void push_xyz(std::vector &v, const Scene_edit_box_item::Kernel::Point_3& p, - qglviewer::Vec center_ = qglviewer::Vec(0,0,0)) + CGAL::qglviewer::Vec center_ = CGAL::qglviewer::Vec(0,0,0)) { v.push_back(p.x()-center_.x); v.push_back(p.y()-center_.y); @@ -744,7 +745,7 @@ void Scene_edit_box_item_priv::computeElements() const Scene_edit_box_item::~Scene_edit_box_item() { - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); viewer->setMouseTracking(false); delete d; @@ -763,7 +764,7 @@ Scene_edit_box_item::manipulatedFrame() double Scene_edit_box_item::point(short i, short j) const { - qglviewer::Vec pos(d->vertices[i].position().x()-d->center_.x, + CGAL::qglviewer::Vec pos(d->vertices[i].position().x()-d->center_.x, d->vertices[i].position().y()-d->center_.y, d->vertices[i].position().z()-d->center_.z); return (d->frame->inverseCoordinatesOf(pos))[j]; @@ -909,7 +910,7 @@ void Scene_edit_box_item::highlight(Viewer_interface *viewer) void Scene_edit_box_item::clearHL() { - Viewer_interface* viewer = dynamic_cast(*QGLViewer::QGLViewerPool().begin()); + Viewer_interface* viewer = dynamic_cast(*CGAL::QGLViewer::QGLViewerPool().begin()); viewer->makeCurrent(); d->hl_normal.clear(); d->hl_vertex.clear(); @@ -986,10 +987,10 @@ void Scene_edit_box_item::clearHL() void Scene_edit_box_item_priv::reset_selection() { selection_on = false; - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); viewer->setManipulatedFrame(frame); - viewer->setMouseBinding(Qt::ShiftModifier, Qt::LeftButton, QGLViewer::SELECT); - constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::FREE); + viewer->setMouseBinding(Qt::ShiftModifier, Qt::LeftButton, CGAL::qglviewer::SELECT); + constraint.setTranslationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FREE); selected_vertices.clear(); } @@ -1015,7 +1016,7 @@ bool Scene_edit_box_item::eventFilter(QObject *obj, QEvent *event) { bool found = false; QApplication::setOverrideCursor(Qt::DragMoveCursor); - qglviewer::Vec pos = viewer->camera()->pointUnderPixel(d->picked_pixel, found); + CGAL::qglviewer::Vec pos = viewer->camera()->pointUnderPixel(d->picked_pixel, found); if(found) { d->rf_last_pos = pos; @@ -1028,7 +1029,7 @@ bool Scene_edit_box_item::eventFilter(QObject *obj, QEvent *event) if(type == 0) { d->selected_vertices.push_back(&d->vertices[picked]); - d->constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::FREE); + d->constraint.setTranslationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FREE); d->remodel_frame->setConstraint(&d->constraint); } else if(type == 1) @@ -1037,8 +1038,8 @@ bool Scene_edit_box_item::eventFilter(QObject *obj, QEvent *event) d->selected_vertices.push_back(d->edges[picked].target); Kernel::Point_3 s(d->edges[picked].source->position()), t(d->edges[picked].target->position()); - qglviewer::Vec normal(t.x()-s.x(), t.y()-s.y(), t.z()-s.z()); - d->constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::PLANE); + CGAL::qglviewer::Vec normal(t.x()-s.x(), t.y()-s.y(), t.z()-s.z()); + d->constraint.setTranslationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::PLANE); d->constraint.setTranslationConstraintDirection(normal); d->remodel_frame->setConstraint(&d->constraint); } @@ -1052,16 +1053,16 @@ bool Scene_edit_box_item::eventFilter(QObject *obj, QEvent *event) QVector3D n = QVector3D::crossProduct(a,b); d->remodel_frame->setConstraint(&d->constraint); - d->constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::AXIS); - d->constraint.setTranslationConstraintDirection(qglviewer::Vec(n.x(), n.y(), n.z())); + d->constraint.setTranslationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::AXIS); + d->constraint.setTranslationConstraintDirection(CGAL::qglviewer::Vec(n.x(), n.y(), n.z())); } viewer->setManipulatedFrame(d->remodel_frame); viewer->setMouseBinding( Qt::NoModifier, Qt::LeftButton, - QGLViewer::FRAME, - QGLViewer::TRANSLATE); + CGAL::qglviewer::FRAME, + CGAL::qglviewer::TRANSLATE); } else { @@ -1078,7 +1079,7 @@ bool Scene_edit_box_item::eventFilter(QObject *obj, QEvent *event) if(d->selection_on) { d->remodel_frame->setOrientation(d->frame->orientation()); - qglviewer::Vec td(d->remodel_frame->transformOf(d->remodel_frame->position() - d->rf_last_pos)); + CGAL::qglviewer::Vec td(d->remodel_frame->transformOf(d->remodel_frame->position() - d->rf_last_pos)); QVector3D dir(td.x, td.y, td.z); d->remodel_box(dir); } @@ -1108,8 +1109,8 @@ bool Scene_edit_box_item::eventFilter(QObject *obj, QEvent *event) viewer->setMouseBinding( Qt::NoModifier, Qt::LeftButton, - QGLViewer::CAMERA, - QGLViewer::ROTATE); + CGAL::qglviewer::CAMERA, + CGAL::qglviewer::ROTATE); } else if(event->type() == QEvent::KeyRelease) { @@ -1180,8 +1181,8 @@ void Scene_edit_box_item_priv::draw_picking(Viewer_interface* viewer) void Scene_edit_box_item_priv::remodel_box(const QVector3D &dir) { - qglviewer::AxisPlaneConstraint::Type prev_cons = constraint.translationConstraintType(); - constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::FREE); + CGAL::qglviewer::AxisPlaneConstraint::Type prev_cons = constraint.translationConstraintType(); + constraint.setTranslationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FREE); Q_FOREACH(Scene_edit_box_item::vertex* selected_vertex, selected_vertices ) { int id = selected_vertex->id; diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_facegraph_transform_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_facegraph_transform_item.cpp index 188ec2733ef..cc0759ff61c 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_facegraph_transform_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_facegraph_transform_item.cpp @@ -5,7 +5,7 @@ struct Scene_facegraph_transform_item_priv { - Scene_facegraph_transform_item_priv(const qglviewer::Vec& pos,FaceGraph* sm, + Scene_facegraph_transform_item_priv(const CGAL::qglviewer::Vec& pos,FaceGraph* sm, const QString name, Scene_facegraph_transform_item *parent) : manipulable(false), frame(new CGAL::Three::Scene_item::ManipulatedFrame()), @@ -14,7 +14,7 @@ struct Scene_facegraph_transform_item_priv item_name(name) { item = parent; - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); frame->setPosition(pos+offset); nb_lines = 0; } @@ -34,9 +34,9 @@ struct Scene_facegraph_transform_item_priv }; bool manipulable; - qglviewer::ManipulatedFrame* frame; + CGAL::qglviewer::ManipulatedFrame* frame; FaceGraph* facegraph; - qglviewer::Vec center_; + CGAL::qglviewer::Vec center_; Scene_facegraph_transform_item *item; QMatrix4x4 f_matrix; const QString item_name; @@ -46,7 +46,7 @@ struct Scene_facegraph_transform_item_priv mutable std::size_t nb_lines; }; -Scene_facegraph_transform_item::Scene_facegraph_transform_item(const qglviewer::Vec& pos, FaceGraph* sm, +Scene_facegraph_transform_item::Scene_facegraph_transform_item(const CGAL::qglviewer::Vec& pos, FaceGraph* sm, const QString name): Scene_item(Scene_facegraph_transform_item_priv::NbOfVbos,Scene_facegraph_transform_item_priv::NbOfVaos) { @@ -151,8 +151,8 @@ Scene_facegraph_transform_item::compute_bbox() const { ++it) { bbox = bbox + get(vpmap, *it).bbox(); } - qglviewer::Vec min(bbox.xmin(),bbox.ymin(),bbox.zmin()); - qglviewer::Vec max(bbox.xmax(),bbox.ymax(),bbox.zmax()); + CGAL::qglviewer::Vec min(bbox.xmin(),bbox.ymin(),bbox.zmin()); + CGAL::qglviewer::Vec max(bbox.xmax(),bbox.ymax(),bbox.zmax()); _bbox = Bbox(min.x,min.y,min.z, max.x,max.y,max.z); } @@ -168,7 +168,7 @@ void Scene_facegraph_transform_item::invalidateOpenGLBuffers() bool Scene_facegraph_transform_item::manipulatable() const { return d->manipulable; } CGAL::Three::Scene_item::ManipulatedFrame* Scene_facegraph_transform_item::manipulatedFrame() { return d->frame; } void Scene_facegraph_transform_item::setManipulatable(bool b = true) { d->manipulable = b;} -const qglviewer::Vec& Scene_facegraph_transform_item::center() const { return d->center_; } +const CGAL::qglviewer::Vec& Scene_facegraph_transform_item::center() const { return d->center_; } Scene_facegraph_transform_item::~Scene_facegraph_transform_item() { delete d; Q_EMIT killed(); } void Scene_facegraph_transform_item::setFMatrix(double matrix[16]) { diff --git a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_facegraph_transform_item.h b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_facegraph_transform_item.h index 0b4235228b8..5bf5f8de84e 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_facegraph_transform_item.h +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_facegraph_transform_item.h @@ -13,8 +13,8 @@ #include "Scene_polyhedron_item.h" #endif -#include -#include +#include +#include #include @@ -33,7 +33,7 @@ class SCENE_FACEGRAPH_TRANSFORM_ITEM_EXPORT Scene_facegraph_transform_item Q_OBJECT public: - Scene_facegraph_transform_item(const qglviewer::Vec& pos, FaceGraph *sm, + Scene_facegraph_transform_item(const CGAL::qglviewer::Vec& pos, FaceGraph *sm, const QString name); Scene_item* clone() const{return NULL;} QString toolTip() const; @@ -43,7 +43,7 @@ public: bool manipulatable() const; ManipulatedFrame* manipulatedFrame(); void setManipulatable(bool); - const qglviewer::Vec& center() const; + const CGAL::qglviewer::Vec& center() const; virtual bool supportsRenderingMode(RenderingMode m) const { return m==Wireframe ; } virtual void invalidateOpenGLBuffers(); virtual bool keyPressEvent(QKeyEvent*); diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt index a7ded34a88f..6970f0255c5 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/CMakeLists.txt @@ -87,11 +87,13 @@ polyhedron_demo_plugin(polyhedron_stitching_plugin Polyhedron_stitching_plugin) target_link_libraries(polyhedron_stitching_plugin PUBLIC scene_polyhedron_item scene_surface_mesh_item scene_polylines_item) qt5_wrap_ui( selectionUI_FILES Selection_widget.ui) -polyhedron_demo_plugin(selection_plugin Selection_plugin ${selectionUI_FILES}) +add_library(selection_plugin SHARED Selection_plugin.cpp ${selectionUI_FILES}) +#polyhedron_demo_plugin(selection_plugin Selection_plugin ${selectionUI_FILES}) target_link_libraries(selection_plugin PUBLIC scene_polyhedron_selection_item scene_points_with_normal_item scene_polylines_item) qt5_wrap_ui( selectionUI_FILES Selection_widget.ui) -polyhedron_demo_plugin(selection_sm_plugin Selection_plugin ${selectionUI_FILES}) +add_library(selection_sm_plugin SHARED Selection_plugin.cpp ${selectionUI_FILES}) +#polyhedron_demo_plugin(selection_sm_plugin Selection_plugin ${selectionUI_FILES}) target_link_libraries(selection_sm_plugin PUBLIC scene_surface_mesh_selection_item scene_points_with_normal_item scene_polylines_item) target_compile_definitions(selection_sm_plugin PUBLIC "-DUSE_SURFACE_MESH" ) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp index e7a5e8dff1a..36551e5ad84 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include @@ -76,7 +76,7 @@ public: struct Polyline_data { Scene_polylines_item* polyline; fg_halfedge_descriptor halfedge; - qglviewer::Vec position; + CGAL::qglviewer::Vec position; }; struct Mouse_keyboard_state { @@ -98,7 +98,7 @@ public: get_holes(); active_hole = polyline_data_list.end(); - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); viewer->installEventFilter(this); mainWindow->installEventFilter(this); @@ -182,7 +182,7 @@ public: // activate closest hole if(event->type() == QEvent::HoverMove) { - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); const QPoint& p = viewer->mapFromGlobal(QCursor::pos()); bool need_repaint = activate_closest_hole(p.x(), p.y()); if(need_repaint) { Q_EMIT itemChanged(); } @@ -206,7 +206,7 @@ private: void get_holes() { // save selected hole positions to keep selected holes selected // we just use center position of holes for identification which might not work good for advanced cases... - std::vector selected_hole_positions; + std::vector selected_hole_positions; for(Selected_holes_set::const_iterator it = selected_holes.begin(); it != selected_holes.end(); ++it) { selected_hole_positions.push_back((*it)->position); } @@ -226,7 +226,7 @@ private: polyline_data.polyline->polylines.push_back(Scene_polylines_item::Polyline()); polyline_data.halfedge = hd; - qglviewer::Vec center; + CGAL::qglviewer::Vec center; int counter = 0; fg_halfedge_descriptor hf_around_facet; BOOST_FOREACH(hf_around_facet, halfedges_around_face(hd,poly)){ @@ -234,7 +234,7 @@ private: visited.insert(hf_around_facet); const Point_3& p = get(vpm,target(hf_around_facet, poly)); polyline_data.polyline->polylines.front().push_back(p); - center += qglviewer::Vec(p.x(), p.y(), p.z()); + center += CGAL::qglviewer::Vec(p.x(), p.y(), p.z()); ++counter; } hf_around_facet = *halfedges_around_face(hd,poly).first; @@ -257,8 +257,8 @@ private: Face_graph& poly = *poly_item->polyhedron(); - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); - qglviewer::Camera* camera = viewer->camera(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); + CGAL::qglviewer::Camera* camera = viewer->camera(); Polyline_data_list::const_iterator min_it; double min_dist = (std::numeric_limits::max)(); @@ -267,7 +267,7 @@ private: { #if 0 /* use center of polyline to measure distance - performance wise */ - const qglviewer::Vec& pos_it = camera->projectedCoordinatesOf(it->position); + const CGAL::qglviewer::Vec& pos_it = camera->projectedCoordinatesOf(it->position); float dist = std::pow(pos_it.x - x, 2) + std::pow(pos_it.y - y, 2); if(dist < min_dist) { min_dist = dist; @@ -278,9 +278,9 @@ private: /* use polyline points to measure distance - might hurt performance for large holes */ BOOST_FOREACH(fg_halfedge_descriptor hf_around_facet, halfedges_around_face(it->halfedge,poly)){ const Point_3& p_1 = get(vpm,target(hf_around_facet,poly)); - const qglviewer::Vec& pos_it_1 = camera->projectedCoordinatesOf(qglviewer::Vec(p_1.x(), p_1.y(), p_1.z())); + const CGAL::qglviewer::Vec& pos_it_1 = camera->projectedCoordinatesOf(CGAL::qglviewer::Vec(p_1.x(), p_1.y(), p_1.z())); const Point_3& p_2 = get(vpm,target(opposite(hf_around_facet,poly),poly)); - const qglviewer::Vec& pos_it_2 = camera->projectedCoordinatesOf(qglviewer::Vec(p_2.x(), p_2.y(), p_2.z())); + const CGAL::qglviewer::Vec& pos_it_2 = camera->projectedCoordinatesOf(CGAL::qglviewer::Vec(p_2.x(), p_2.y(), p_2.z())); Kernel::Segment_2 s(Kernel::Point_2(pos_it_1.x, pos_it_1.y), Kernel::Point_2(pos_it_2.x, pos_it_2.y)); double dist = CGAL::squared_distance(s, xy); diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Isotropic_remeshing_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Isotropic_remeshing_plugin.cpp index 12b3e251c11..45ce18f78fc 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Isotropic_remeshing_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Isotropic_remeshing_plugin.cpp @@ -400,6 +400,7 @@ public Q_SLOTS: *selection_item->polyhedron(), selection_item->constrained_edges_pmap(), get(CGAL::vertex_point, *selection_item->polyhedron()), + CGAL::Static_property_map(1), 4. / 3. * target_length)) { QApplication::restoreOverrideCursor(); diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Polyhedron_slicer_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Polyhedron_slicer_plugin.cpp index 570dcc29d8d..ec17a5cd5b9 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Polyhedron_slicer_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Polyhedron_slicer_plugin.cpp @@ -92,7 +92,7 @@ private: template void intersection_of_plane_Polyhedra_3_using_AABB_wrapper(TriangleMesh& mesh, const std::vector& planes, - const std::vector& plane_positions, + const std::vector& plane_positions, std::list >& polylines); }; // end Polyhedron_demo_polyhedron_slicer_plugin @@ -159,14 +159,14 @@ void Polyhedron_demo_polyhedron_slicer_plugin::slicer_widget_action(){ // when manipulated frame of plane is modified, update line-edits void Polyhedron_demo_polyhedron_slicer_plugin::plane_manipulated_frame_modified() { - qglviewer::ManipulatedFrame* mf = plane_item->manipulatedFrame(); - const qglviewer::Vec& pos = mf->position(); + CGAL::qglviewer::ManipulatedFrame* mf = plane_item->manipulatedFrame(); + const CGAL::qglviewer::Vec& pos = mf->position(); ui_widget.Center_x->setText(QString::number(pos.x)); ui_widget.Center_y->setText(QString::number(pos.y)); ui_widget.Center_z->setText(QString::number(pos.z)); - const qglviewer::Vec& base_1 = mf->inverseTransformOf(qglviewer::Vec(1., 0., 0.)); - const qglviewer::Vec& base_2 = mf->inverseTransformOf(qglviewer::Vec(0., 1., 0.)); + const CGAL::qglviewer::Vec& base_1 = mf->inverseTransformOf(CGAL::qglviewer::Vec(1., 0., 0.)); + const CGAL::qglviewer::Vec& base_2 = mf->inverseTransformOf(CGAL::qglviewer::Vec(0., 1., 0.)); ui_widget.Base_1_x->setText(QString::number(base_1.x)); ui_widget.Base_1_y->setText(QString::number(base_1.y)); @@ -179,7 +179,7 @@ void Polyhedron_demo_polyhedron_slicer_plugin::plane_manipulated_frame_modified( // when Update Plane button is clicked, update manipulated frame of plane with line-edits bool Polyhedron_demo_polyhedron_slicer_plugin::on_Update_plane_button_clicked() { - qglviewer::ManipulatedFrame* mf = plane_item->manipulatedFrame(); + CGAL::qglviewer::ManipulatedFrame* mf = plane_item->manipulatedFrame(); // get center bool ok_1 = true, ok_2 = true, ok_3 = true; double center_x = ui_widget.Center_x->text().toDouble(&ok_1); @@ -199,13 +199,13 @@ bool Polyhedron_demo_polyhedron_slicer_plugin::on_Update_plane_button_clicked() { print_message("Error: Base-1, Base-2 coordinates not convertible to double."); return false; } // compute other axis - qglviewer::Vec base_1(bases[0], bases[1], bases[2]); - qglviewer::Vec base_2(bases[3], bases[4], bases[5]); - qglviewer::Vec other = cross(base_1, base_2); + CGAL::qglviewer::Vec base_1(bases[0], bases[1], bases[2]); + CGAL::qglviewer::Vec base_2(bases[3], bases[4], bases[5]); + CGAL::qglviewer::Vec other = cross(base_1, base_2); if(other.norm() == 0.0) { print_message("Error: collinear base vectors are not accepted!"); return false; } // set orientation - qglviewer::Quaternion orientation_from_bases; + CGAL::qglviewer::Quaternion orientation_from_bases; orientation_from_bases.setFromRotatedBasis(base_1, base_2, other); oldState = mf->blockSignals(true); // dont let it signal, it will invoke plane_manipulated_frame_modified otherwise @@ -228,15 +228,15 @@ void Polyhedron_demo_polyhedron_slicer_plugin::on_Generate_button_clicked() QString item_name = (item)?item->name() : sm_item->name(); if(!on_Update_plane_button_clicked()) { return; } - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); QApplication::setOverrideCursor(Qt::WaitCursor); // get plane position and normal - qglviewer::ManipulatedFrame* mf = plane_item->manipulatedFrame(); - const qglviewer::Vec& pos = mf->position()-offset; + CGAL::qglviewer::ManipulatedFrame* mf = plane_item->manipulatedFrame(); + const CGAL::qglviewer::Vec& pos = mf->position()-offset; // WARNING: due to fp arithmetic (setting quaternion based orientation from base vectors then getting plane normal back from this orientation) // for base vectors like: 1,0,0 - 0,1,0 we might not have exact corresponding normal vector. // So not using below normal but construct plane directly from bases from text boxes - const qglviewer::Vec& n = mf->inverseTransformOf(qglviewer::Vec(0.f, 0.f, 1.f)); + const CGAL::qglviewer::Vec& n = mf->inverseTransformOf(CGAL::qglviewer::Vec(0.f, 0.f, 1.f)); // get bases double bases[6]; @@ -263,12 +263,12 @@ void Polyhedron_demo_polyhedron_slicer_plugin::on_Generate_button_clicked() // continue generating planes while inside bbox std::vector planes; - std::vector plane_positions; + std::vector plane_positions; for(int dir = 1, step = 0; /* */ ; ++step) { double distance_norm = (dir * step) * distance_with_planes; - qglviewer::Vec new_pos = pos + (n*distance_norm); + CGAL::qglviewer::Vec new_pos = pos + (n*distance_norm); //Epic_kernel::Plane_3 plane(n[0], n[1], n[2], - n * new_pos); Epic_kernel::Point_3 new_pos_cgal(new_pos[0], new_pos[1], new_pos[2]); @@ -352,11 +352,11 @@ template void Polyhedron_demo_polyhedron_slicer_plugin::intersection_of_plane_Polyhedra_3_using_AABB_wrapper( TriangleMesh& poly, const std::vector& planes, - const std::vector& plane_positions, + const std::vector& plane_positions, std::list >& polylines) { CGAL::Polygon_mesh_slicer slicer(poly); - std::vector::const_iterator plane_position_it = plane_positions.begin(); + std::vector::const_iterator plane_position_it = plane_positions.begin(); for(std::vector::const_iterator plane_it = planes.begin(); plane_it != planes.end(); ++plane_it, ++plane_position_it) slicer(*plane_it, std::front_inserter(polylines)); diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Scene_facegraph_item_k_ring_selection.h b/Polyhedron/demo/Polyhedron/Plugins/PMP/Scene_facegraph_item_k_ring_selection.h index 994c5b19384..72b65c0f3bb 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Scene_facegraph_item_k_ring_selection.h +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Scene_facegraph_item_k_ring_selection.h @@ -9,7 +9,7 @@ #include "Polyhedron_type.h" #endif #include -#include +#include #include #include #include @@ -109,7 +109,7 @@ public: void setEditMode(bool b) { is_edit_mode = b; - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); //for highlighting viewer->setMouseTracking(true); } @@ -130,14 +130,10 @@ public: poly_item->enable_facets_picking(true); poly_item->set_color_vector_read_only(true); #endif - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); viewer->installEventFilter(this); mw->installEventFilter(this); -#if QGLVIEWER_VERSION >= 0x020501 viewer->setMouseBindingDescription(Qt::Key_D, Qt::ShiftModifier, Qt::LeftButton, "(When in selection plugin) Removes the clicked primitive from the selection. "); -#else - viewer->setMouseBindingDescription(Qt::SHIFT + Qt::LeftButton, "(When in selection plugin) When D is pressed too, removes the clicked primitive from the selection. "); -#endif connect(poly_item, SIGNAL(selected_vertex(void*)), this, SLOT(vertex_has_been_selected(void*))); connect(poly_item, SIGNAL(selected_facet(void*)), this, SLOT(facet_has_been_selected(void*))); connect(poly_item, SIGNAL(selected_edge(void*)), this, SLOT(edge_has_been_selected(void*))); @@ -201,17 +197,30 @@ public Q_SLOTS: { if(is_ready_to_paint_select) { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); // paint with mouse move event - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); - qglviewer::Camera* camera = viewer->camera(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); + CGAL::qglviewer::Camera* camera = viewer->camera(); viewer->makeCurrent(); bool found = false; - const qglviewer::Vec& point = camera->pointUnderPixel(paint_pos, found) - offset; + const CGAL::qglviewer::Vec& point = camera->pointUnderPixel(paint_pos, found) - offset; if(found) { - const qglviewer::Vec& orig = camera->position() - offset; - const qglviewer::Vec& dir = point - orig; + CGAL::qglviewer::Vec orig; + CGAL::qglviewer::Vec dir; + if(camera->type() == CGAL::qglviewer::Camera::PERSPECTIVE) + { + orig = camera->position() - offset; + dir = point - orig; + } + else + { + dir = camera->viewDirection(); + orig = CGAL::qglviewer::Vec(point.x - dir.x, + point.y - dir.y, + point.z - dir.z); + + } poly_item->select(orig.x, orig.y, orig.z, dir.x, dir.y, dir.z); } viewer->doneCurrent(); @@ -221,10 +230,10 @@ public Q_SLOTS: void lasso_selection() { - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); - const qglviewer::Vec offset = static_cast(viewer)->offset(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); + const CGAL::qglviewer::Vec offset = static_cast(viewer)->offset(); - qglviewer::Camera* camera = viewer->camera(); + CGAL::qglviewer::Camera* camera = viewer->camera(); const FaceGraph& poly = *poly_item->polyhedron(); std::set face_sel; boost::property_map::const_type vpmap = get(boost::vertex_point, poly); @@ -234,8 +243,8 @@ public Q_SLOTS: BOOST_FOREACH(fg_vertex_descriptor v, CGAL::vertices_around_face(halfedge(f, poly), poly)) { FG_Traits::Point_3 p = get(vpmap, v); - qglviewer::Vec vp(p.x(), p.y(), p.z()); - qglviewer::Vec vsp = camera->projectedCoordinatesOf(vp+offset); + CGAL::qglviewer::Vec vp(p.x(), p.y(), p.z()); + CGAL::qglviewer::Vec vsp = camera->projectedCoordinatesOf(vp+offset); if(is_vertex_selected(vsp)) { face_sel.insert(f); @@ -272,7 +281,6 @@ public Q_SLOTS: BOOST_FOREACH(fg_face_descriptor f, face_sel) { - int cc_id = get(fccmap, f); if(is_cc_done[cc_id]) { @@ -290,15 +298,27 @@ public Q_SLOTS: } if(total == 0) continue; - qglviewer::Vec center(x/(double)total, y/(double)total, z/(double)total); - const qglviewer::Vec& orig = camera->position() - offset; - qglviewer::Vec direction = center - orig; + CGAL::qglviewer::Vec center(x/(double)total, y/(double)total, z/(double)total); + CGAL::qglviewer::Vec orig; + CGAL::qglviewer::Vec dir; + if(camera->type() == CGAL::qglviewer::Camera::PERSPECTIVE) + { + orig = camera->position() - offset; + dir = center - orig; + } + else + { + dir = camera->viewDirection(); + orig = CGAL::qglviewer::Vec(center.x - dir.x, + center.y - dir.y, + center.z - dir.z); + } if(poly_item->intersect_face(orig.x, orig.y, orig.z, - direction.x, - direction.y, - direction.z, + dir.x, + dir.y, + dir.z, f)) { is_cc_done[cc_id] = true; @@ -322,11 +342,11 @@ public Q_SLOTS: BOOST_FOREACH(fg_halfedge_descriptor h, CGAL::halfedges_around_face(halfedge(f, poly), poly)) { FG_Traits::Point_3 p = get(vpmap, target(h, poly)); - qglviewer::Vec vp1(p.x(), p.y(), p.z()); - qglviewer::Vec vsp1 = camera->projectedCoordinatesOf(vp1+offset); + CGAL::qglviewer::Vec vp1(p.x(), p.y(), p.z()); + CGAL::qglviewer::Vec vsp1 = camera->projectedCoordinatesOf(vp1+offset); p = get(vpmap, target(opposite(h, poly), poly)); - qglviewer::Vec vp2(p.x(), p.y(), p.z()); - qglviewer::Vec vsp2 = camera->projectedCoordinatesOf(vp2+offset); + CGAL::qglviewer::Vec vp2(p.x(), p.y(), p.z()); + CGAL::qglviewer::Vec vsp2 = camera->projectedCoordinatesOf(vp2+offset); if(is_vertex_selected(vsp1) || is_vertex_selected(vsp2)) e_sel.insert(edge(h, poly)); } @@ -342,8 +362,8 @@ public Q_SLOTS: BOOST_FOREACH(fg_vertex_descriptor v, CGAL::vertices_around_face(halfedge(f, poly), poly)) { FG_Traits::Point_3 p = get(vpmap, v); - qglviewer::Vec vp(p.x(), p.y(), p.z()); - qglviewer::Vec vsp = camera->projectedCoordinatesOf(vp+offset); + CGAL::qglviewer::Vec vp(p.x(), p.y(), p.z()); + CGAL::qglviewer::Vec vsp = camera->projectedCoordinatesOf(vp+offset); if(is_vertex_selected(vsp)) v_sel.insert(v); } @@ -360,19 +380,32 @@ public Q_SLOTS: void highlight() { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); if(is_ready_to_highlight) { // highlight with mouse move event - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); - qglviewer::Camera* camera = viewer->camera(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); + CGAL::qglviewer::Camera* camera = viewer->camera(); viewer->makeCurrent(); bool found = false; - const qglviewer::Vec& point = camera->pointUnderPixel(hl_pos, found) - offset; + const CGAL::qglviewer::Vec& point = camera->pointUnderPixel(hl_pos, found) - offset; if(found) { - const qglviewer::Vec& orig = camera->position() - offset; - const qglviewer::Vec& dir = point - orig; + CGAL::qglviewer::Vec orig; + CGAL::qglviewer::Vec dir; + if(camera->type() == CGAL::qglviewer::Camera::PERSPECTIVE) + { + orig = camera->position() - offset; + dir = point - orig; + } + else + { + dir = camera->viewDirection(); + orig = CGAL::qglviewer::Vec(point.x - dir.x, + point.y - dir.y, + point.z - dir.z); + + } is_highlighting = true; poly_item->select(orig.x, orig.y, orig.z, dir.x, dir.y, dir.z); is_highlighting = false; @@ -548,7 +581,7 @@ protected: return false; if(target == mainwindow) { - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); viewer->setFocus(); return false; } @@ -567,11 +600,7 @@ protected: if (event->type() != QEvent::MouseMove) { //Create a QImage of the screen and paint the lasso on top of it -#if QGLVIEWER_VERSION >= 0x020700 - background = static_cast(*QGLViewer::QGLViewerPool().begin())->grabFramebuffer(); -#else - background = static_cast(*QGLViewer::QGLViewerPool().begin())->grabFrameBuffer(); -#endif + background = static_cast(*CGAL::QGLViewer::QGLViewerPool().begin())->grabFramebuffer(); } sample_mouse_path(background); } @@ -582,7 +611,7 @@ protected: { if(target == mainwindow) { - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); viewer->setFocus(); return false; } @@ -625,7 +654,7 @@ protected: void sample_mouse_path(QImage& background) { - CGAL::Three::Viewer_interface* viewer = static_cast(*QGLViewer::QGLViewerPool().begin()); + CGAL::Three::Viewer_interface* viewer = static_cast(*CGAL::QGLViewer::QGLViewerPool().begin()); viewer->makeCurrent(); const QPoint& p = viewer->mapFromGlobal(QCursor::pos()); contour_2d.push_back (FG_Traits::Point_2 (p.x(), p.y())); @@ -636,8 +665,11 @@ protected: pen.setColor(QColor(Qt::green)); pen.setWidth(3); + //Create a QImage of the screen and paint the lasso on top of it QImage temp(background); QPainter *painter = new QPainter(&temp); + + //painter->begin(&image); painter->setPen(pen); for(std::size_t i=0; isize(); ++i) @@ -646,7 +678,10 @@ protected: if(!poly.empty()) for(std::size_t j=0; jdrawLine(poly[j].x(), poly[j].y(), poly[j+1].x(), poly[j+1].y()); + painter->drawLine(int(poly[j].x()), + int(poly[j].y()), + int(poly[j+1].x()), + int(poly[j+1].y())); } } painter->end(); @@ -665,7 +700,7 @@ protected: lasso = Polygon_2 (contour_2d.begin (), contour_2d.end ()); } - bool is_vertex_selected (qglviewer::Vec& p) + bool is_vertex_selected (CGAL::qglviewer::Vec& p) { if (domain_rectangle.xmin () < p.x && p.x < domain_rectangle.xmax () && diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp index 885a74ba5ac..a6cf3a63299 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Selection_plugin.cpp @@ -761,6 +761,9 @@ public Q_SLOTS: tr("Degenerated faces have been detected. Problems may occur " "for operations other tha \"Move point\". ")); } + //remove lasso mode + selection_item->set_lasso_mode(false); + ui_widget.lassoCheckBox->setChecked(false); Q_EMIT save_handleType(); on_editionBox_changed(ui_widget.editionBox->currentIndex()); break; diff --git a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Alpha_shape_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Alpha_shape_plugin.cpp index bdea82e9c05..42bbd329ff3 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Alpha_shape_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Alpha_shape_plugin.cpp @@ -278,7 +278,7 @@ Scene_alpha_shape_item::Scene_alpha_shape_item(Scene_points_with_normal_item *po { QApplication::setOverrideCursor(Qt::WaitCursor); _bbox = point_set_item->bbox(); - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); vertices.reserve(point_set.size() * 3); CGAL::Timer timer; timer.start(); diff --git a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Features_detection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Features_detection_plugin.cpp index 1f3a07194c7..6e463e7c875 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Features_detection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Features_detection_plugin.cpp @@ -1,3 +1,4 @@ +#include #include #include #include diff --git a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp index 60fafc6116f..14a237d3043 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include #include @@ -80,7 +80,7 @@ public: void render(QImage& image) const { - CGAL::Three::Viewer_interface* viewer = static_cast(*QGLViewer::QGLViewerPool().begin()); + CGAL::Three::Viewer_interface* viewer = static_cast(*CGAL::QGLViewer::QGLViewerPool().begin()); QPen pen; pen.setColor(QColor(Qt::green)); @@ -146,7 +146,7 @@ public: void sample_mouse_path(QImage& image) { - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); const QPoint& p = viewer->mapFromGlobal(QCursor::pos()); if (rectangle && contour_2d.size () == 2) @@ -172,7 +172,7 @@ public: domain_freeform = Polygon_2 (contour_2d.begin (), contour_2d.end ()); } - bool is_selected (qglviewer::Vec& p) + bool is_selected (CGAL::qglviewer::Vec& p) { if (domain_rectangle.xmin () < p.x && p.x < domain_rectangle.xmax () && @@ -205,8 +205,8 @@ class Selection_test { Point_set* point_set; bool* selected; - qglviewer::Camera* camera; - const qglviewer::Vec offset; + CGAL::qglviewer::Camera* camera; + const CGAL::qglviewer::Vec offset; Scene_edit_box_item* edit_box; Scene_point_set_selection_visualizer* visualizer; const Ui::PointSetSelection& ui_widget; @@ -216,8 +216,8 @@ public: Selection_test(Point_set* point_set, bool* selected, - qglviewer::Camera* camera, - const qglviewer::Vec offset, + CGAL::qglviewer::Camera* camera, + const CGAL::qglviewer::Vec offset, Scene_edit_box_item* edit_box, Scene_point_set_selection_visualizer* visualizer, const Ui::PointSetSelection& ui_widget) @@ -245,11 +245,13 @@ public: bool already_selected = point_set->is_selected (it); const Kernel::Point_3& p = point_set->point (*it); - qglviewer::Vec vp (p.x (), p.y (), p.z ()); - qglviewer::Vec vsp = camera->projectedCoordinatesOf (vp + offset); + CGAL::qglviewer::Vec vp (p.x (), p.y (), p.z ()); bool now_selected = false; if(!ui_widget.box->isChecked()) + { + CGAL::qglviewer::Vec vsp = camera->projectedCoordinatesOf (vp + offset); now_selected = visualizer->is_selected (vsp); + } else if(edit_box) { if(p.x() >= edit_box->point(0,0) - offset.x && @@ -619,7 +621,7 @@ public: shift_pressing = false; ctrl_pressing = false; - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); viewer->installEventFilter(this); mainWindow->installEventFilter(this); @@ -650,12 +652,7 @@ protected: shift_pressing = modifiers.testFlag(Qt::ShiftModifier); ctrl_pressing = modifiers.testFlag(Qt::ControlModifier); -#if QGLVIEWER_VERSION >= 0x020700 - background = static_cast(*QGLViewer::QGLViewerPool().begin())->grabFramebuffer(); -#else - background = static_cast(*QGLViewer::QGLViewerPool().begin())->grabFrameBuffer(); - -#endif + background = static_cast(*CGAL::QGLViewer::QGLViewerPool().begin())->grabFramebuffer(); } // mouse events @@ -670,19 +667,19 @@ protected: { QApplication::setOverrideCursor(Qt::WaitCursor); - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); bool found = false; QPoint pixel(mouseEvent->pos().x(), viewer->camera()->screenHeight() - 1 - mouseEvent->pos().y()); - qglviewer::Vec point = viewer->camera()->pointUnderPixel(mouseEvent->pos(), + CGAL::qglviewer::Vec point = viewer->camera()->pointUnderPixel(mouseEvent->pos(), found); if(!found) { QApplication::restoreOverrideCursor(); return false; } - const qglviewer::Vec offset = static_cast(viewer)->offset(); + const CGAL::qglviewer::Vec offset = static_cast(viewer)->offset(); point = point - offset; neighborhood.point_set (point_set_item).grow_region @@ -696,7 +693,7 @@ protected: else if (!visualizer) { QApplication::setOverrideCursor(Qt::CrossCursor); - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); if (viewer->camera()->frame()->isSpinning()) viewer->camera()->frame()->stopSpinning(); @@ -734,7 +731,7 @@ protected: select_points(); visualizer = NULL; QApplication::restoreOverrideCursor(); - static_cast(*QGLViewer::QGLViewerPool().begin())->set2DSelectionMode(false); + static_cast(*CGAL::QGLViewer::QGLViewerPool().begin())->set2DSelectionMode(false); return true; } // Update selection @@ -751,11 +748,11 @@ protected: qobject_cast(scene->item(scene->mainSelectionIndex())); if(!item) return false; - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); bool found = false; QPoint pixel(m_e->pos().x(), viewer->camera()->screenHeight()-1-m_e->pos().y()); - qglviewer::Vec point = viewer->camera()->pointUnderPixel(m_e->pos(), + CGAL::qglviewer::Vec point = viewer->camera()->pointUnderPixel(m_e->pos(), found); if(!found) return false; @@ -765,7 +762,7 @@ protected: typedef Neighbor_search::Tree Tree; Tree tree(item->point_set()->points().begin(), item->point_set()->points().end()); - const qglviewer::Vec offset = static_cast(viewer)->offset(); + const CGAL::qglviewer::Vec offset = static_cast(viewer)->offset(); point = point - offset; Neighbor_search search(tree, Point(point.x, point.y, point.z), 1); @@ -790,10 +787,10 @@ protected Q_SLOTS: if (ui_widget.new_selection->isChecked()) points->unselect_all(); - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); - const qglviewer::Vec offset = static_cast(viewer)->offset(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); + const CGAL::qglviewer::Vec offset = static_cast(viewer)->offset(); - qglviewer::Camera* camera = viewer->camera(); + CGAL::qglviewer::Camera* camera = viewer->camera(); bool* selected_bitmap = new bool[points->size()]; // std::vector is not thread safe @@ -1002,7 +999,7 @@ public Q_SLOTS: { if(toggle) { - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); qobject_cast(viewer)->set2DSelectionMode(false); edit_box = new Scene_edit_box_item(scene); edit_box->setRenderingMode(Wireframe); diff --git a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Surface_reconstruction_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Surface_reconstruction_plugin.cpp index 63003bb8cdb..8b4e175026d 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Surface_reconstruction_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Surface_reconstruction_plugin.cpp @@ -600,7 +600,7 @@ namespace SurfaceReconstruction } struct Point_set_make_pair_point_index - : public CGAL::unary_function > + : public CGAL::cpp98::unary_function > { const Point_set& point_set; Point_set_make_pair_point_index (const Point_set& point_set) : point_set (point_set) { } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/CMakeLists.txt index 8eb22c6c59e..b55fb050ecf 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/CMakeLists.txt @@ -34,7 +34,7 @@ target_compile_definitions(mesh_simplification_sm_plugin PUBLIC "-DUSE_SURFACE_M qt5_wrap_ui( remeshingUI_FILES Remeshing_dialog.ui) polyhedron_demo_plugin(offset_meshing_plugin Offset_meshing_plugin ${remeshingUI_FILES}) -target_link_libraries(offset_meshing_plugin PUBLIC scene_polyhedron_item scene_polygon_soup_item scene_c2t3_item) +target_link_libraries(offset_meshing_plugin PUBLIC scene_polyhedron_item scene_polygon_soup_item ) qt5_wrap_ui( shortestPathUI_FILES Shortest_path_widget.ui ) polyhedron_demo_plugin(shortest_path_plugin Shortest_path_plugin ${shortestPathUI_FILES}) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/Offset_meshing_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/Offset_meshing_plugin.cpp index b1f6681bc6f..97319141ded 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/Offset_meshing_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/Offset_meshing_plugin.cpp @@ -16,7 +16,6 @@ #include #include "C2t3_type.h" -#include "Scene_c2t3_item.h" #include #include diff --git a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/Scene_polyhedron_shortest_path_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/Scene_polyhedron_shortest_path_item.cpp index ef1213b60df..686827bae93 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/Scene_polyhedron_shortest_path_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/Scene_polyhedron_shortest_path_item.cpp @@ -10,6 +10,8 @@ #include #include + +typedef Scene_polyhedron_shortest_path_item It; struct Scene_polyhedron_shortest_path_item_priv { typedef CGAL::Three::Scene_interface::Bbox Bbox; @@ -60,20 +62,6 @@ struct Scene_polyhedron_shortest_path_item_priv } } - enum Selection_mode - { - INSERT_POINTS_MODE = 0, - REMOVE_POINTS_MODE = 1, - SHORTEST_PATH_MODE = 2 - }; - - enum Primitives_mode - { - VERTEX_MODE = 0, - EDGE_MODE = 1, - FACE_MODE = 2 - }; - enum VAOs { Selected_Edges=0, NbOfVaos @@ -121,7 +109,7 @@ void Scene_polyhedron_shortest_path_item_priv::compute_elements() const QApplication::setOverrideCursor(Qt::WaitCursor); vertices.resize(0); - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); for(Scene_polyhedron_shortest_path_item::Surface_mesh_shortest_path::Source_point_iterator it = m_shortestPaths->source_points_begin(); it != m_shortestPaths->source_points_end(); ++it) { @@ -278,14 +266,14 @@ void Scene_polyhedron_shortest_path_item::invalidateOpenGLBuffers() bool Scene_polyhedron_shortest_path_item_priv::get_mouse_ray(QMouseEvent* mouseEvent, Kernel::Ray_3& outRay) { bool found = false; - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); - const qglviewer::Vec offset = static_cast(viewer)->offset(); - qglviewer::Camera* camera = viewer->camera(); - const qglviewer::Vec point = camera->pointUnderPixel(mouseEvent->pos(), found) - offset; + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); + const CGAL::qglviewer::Vec offset = static_cast(viewer)->offset(); + CGAL::qglviewer::Camera* camera = viewer->camera(); + const CGAL::qglviewer::Vec point = camera->pointUnderPixel(mouseEvent->pos(), found) - offset; if(found) { - const qglviewer::Vec orig = camera->position() - offset; + const CGAL::qglviewer::Vec orig = camera->position() - offset; outRay = Ray_3(Point_3(orig.x, orig.y, orig.z), Point_3(point.x, point.y, point.z)); } @@ -414,35 +402,35 @@ bool Scene_polyhedron_shortest_path_item_priv::run_point_select(const Ray_3& ray .arg(double(faceLocation.second[2]))); switch (m_selectionMode) { - case INSERT_POINTS_MODE: + case It::INSERT_POINTS_MODE: switch (m_primitivesMode) { - case VERTEX_MODE: + case It::VERTEX_MODE: get_as_vertex_point(faceLocation); m_shortestPaths->add_source_point(faceLocation.first, faceLocation.second); break; - case EDGE_MODE: + case It::EDGE_MODE: get_as_edge_point(faceLocation); m_shortestPaths->add_source_point(faceLocation.first, faceLocation.second); break; - case FACE_MODE: + case It::FACE_MODE: m_shortestPaths->add_source_point(faceLocation.first, faceLocation.second); break; } break; - case REMOVE_POINTS_MODE: + case It::REMOVE_POINTS_MODE: remove_nearest_point(faceLocation); break; - case SHORTEST_PATH_MODE: + case It::SHORTEST_PATH_MODE: switch (m_primitivesMode) { - case VERTEX_MODE: + case It::VERTEX_MODE: get_as_vertex_point(faceLocation); break; - case EDGE_MODE: + case It::EDGE_MODE: get_as_edge_point(faceLocation); break; - case FACE_MODE: + case It::FACE_MODE: break; } @@ -588,7 +576,7 @@ void Scene_polyhedron_shortest_path_item::initialize(Scene_face_graph_item* poly this->poly_item = polyhedronItem; d->m_sceneInterface = sceneInterface; connect(polyhedronItem, SIGNAL(item_is_about_to_be_changed()), this, SLOT(poly_item_changed())); - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); viewer->installEventFilter(this); d->m_mainWindow->installEventFilter(this); d->recreate_shortest_path_object(); diff --git a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/Scene_polyhedron_shortest_path_item.h b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/Scene_polyhedron_shortest_path_item.h index 8d0646829d1..5996c22136b 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/Scene_polyhedron_shortest_path_item.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/Scene_polyhedron_shortest_path_item.h @@ -11,7 +11,7 @@ #include "opengl_tools.h" -#include +#include #include #include #include diff --git a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Edit_polyhedron_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Edit_polyhedron_plugin.cpp index 9eeccc3d4f7..730d6447313 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Edit_polyhedron_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Edit_polyhedron_plugin.cpp @@ -602,7 +602,7 @@ void Polyhedron_demo_edit_polyhedron_plugin::importSelection(Scene_polyhedron_se } edit_item->invalidateOpenGLBuffers(); selection_item->setVisible(false); - (*QGLViewer::QGLViewerPool().begin())->update(); + (*CGAL::QGLViewer::QGLViewerPool().begin())->update(); } void Polyhedron_demo_edit_polyhedron_plugin::updateSelectionItems(Scene_facegraph_item* target) diff --git a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.cpp index dccbe7258b0..2b5863bf279 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.cpp @@ -4,6 +4,7 @@ #include "Scene_edit_polyhedron_item.h" #include "Scene_spheres_item.h" #include +#include #include #include #include @@ -82,7 +83,7 @@ struct Scene_edit_polyhedron_item_priv void pivoting_end(Mesh* mesh); template void read_roi(const char* file_name, Mesh* mesh); - void draw_ROI_and_control_vertices(CGAL::Three::Viewer_interface* viewer, qglviewer::ManipulatedFrame* frame, const qglviewer::Vec ¢er) const; + void draw_ROI_and_control_vertices(CGAL::Three::Viewer_interface* viewer, CGAL::qglviewer::ManipulatedFrame* frame, const CGAL::qglviewer::Vec ¢er) const; template void apply_reset_drawing_data(Mesh* mesh, M_Deform_mesh* m_deform_mesh); template @@ -158,7 +159,7 @@ struct Scene_edit_polyhedron_item_priv Mouse_keyboard_state_deformation state; //For constraint rotation - qglviewer::LocalConstraint rot_constraint; + CGAL::qglviewer::LocalConstraint rot_constraint; bool is_rot_free; bool own_poly_item; //indicates if the poly_item should be deleted by the destructor @@ -291,7 +292,7 @@ void Scene_edit_polyhedron_item_priv::init_values() (item->bbox().zmax()-item->bbox().zmin()))) / 15.0; // interleave events of viewer (there is only one viewer) - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); viewer->installEventFilter(item); // create an empty group of control vertices for starting @@ -481,7 +482,7 @@ void Scene_edit_polyhedron_item_priv::initializeBuffers(CGAL::Three::Viewer_inte { std::vector vertices; std::vector *vertices_ptr; - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); if(offset.norm() !=0) { vertices.resize(positions.size()); @@ -702,7 +703,7 @@ void Scene_edit_polyhedron_item_priv::compute_normals_and_vertices(Mesh* mesh) control_points.resize(0); control_color.resize(0); pos_frame_plane.resize(0); - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); Facegraph_selector fs(this); typedef typename boost::property_map::type VertexPointMap; VertexPointMap pmap = get(boost::vertex_point, *mesh); @@ -729,7 +730,7 @@ void Scene_edit_polyhedron_item_priv::compute_normals_and_vertices(Mesh* mesh) for(std::size_t i=0; i >::const_iterator hgb_data = fs.get_ctrl_vertex_frame_map(mesh).begin(); hgb_data != fs.get_ctrl_vertex_frame_map(mesh).end(); ++hgb_data) { @@ -1374,7 +1375,7 @@ bool Scene_edit_polyhedron_item::eventFilter(QObject* /*target*/, QEvent *event) bool ctrl_released_now = !d->state.ctrl_pressing && old_state.ctrl_pressing; if(ctrl_pressed_now || ctrl_released_now || event->type() == QEvent::HoverMove) {// activate a handle manipulated frame - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); const QPoint& p = viewer->mapFromGlobal(QCursor::pos()); bool need_repaint; @@ -1473,7 +1474,7 @@ void Scene_edit_polyhedron_item::drawTransparent(Viewer_interface *viewer) const } template -void Scene_edit_polyhedron_item::draw_frame_plane(QGLViewer* , Mesh* mesh) const +void Scene_edit_polyhedron_item::draw_frame_plane(CGAL::QGLViewer* , Mesh* mesh) const { d->pos_frame_plane.resize(12); Facegraph_selector fs; @@ -1481,18 +1482,18 @@ void Scene_edit_polyhedron_item::draw_frame_plane(QGLViewer* , Mesh* mesh) const hgb_data != fs.get_ctrl_vertex_frame_map(mesh, d).end(); ++hgb_data) { const double diag = scene_diag(); - qglviewer::Vec base1(1,0,0); - qglviewer::Vec base2(0,1,0); + CGAL::qglviewer::Vec base1(1,0,0); + CGAL::qglviewer::Vec base2(0,1,0); - qglviewer::Quaternion orientation=hgb_data->frame->orientation(); + CGAL::qglviewer::Quaternion orientation=hgb_data->frame->orientation(); base1=orientation.rotate(base1); base2=orientation.rotate(base2); - qglviewer::Vec center = hgb_data->calculate_initial_center(); - qglviewer::Vec p1 = center - diag*base1 - diag*base2; - qglviewer::Vec p2 = center + diag*base1 - diag*base2; - qglviewer::Vec p3 = center + diag*base1 + diag*base2; - qglviewer::Vec p4 = center - diag*base1 + diag*base2; + CGAL::qglviewer::Vec center = hgb_data->calculate_initial_center(); + CGAL::qglviewer::Vec p1 = center - diag*base1 - diag*base2; + CGAL::qglviewer::Vec p2 = center + diag*base1 - diag*base2; + CGAL::qglviewer::Vec p3 = center + diag*base1 + diag*base2; + CGAL::qglviewer::Vec p4 = center - diag*base1 + diag*base2; d->pos_frame_plane[0] = p1.x ; d->pos_frame_plane[1] = p1.y; d->pos_frame_plane[2] =p1.z ; d->pos_frame_plane[3] = p2.x ; d->pos_frame_plane[4] = p2.y; d->pos_frame_plane[5] =p2.z ; @@ -1507,10 +1508,10 @@ void Scene_edit_polyhedron_item::draw_frame_plane(QGLViewer* , Mesh* mesh) const } } -void Scene_edit_polyhedron_item_priv::draw_ROI_and_control_vertices(CGAL::Three::Viewer_interface* viewer, qglviewer::ManipulatedFrame* frame, const qglviewer::Vec ¢er) const +void Scene_edit_polyhedron_item_priv::draw_ROI_and_control_vertices(CGAL::Three::Viewer_interface* viewer, CGAL::qglviewer::ManipulatedFrame* frame, const CGAL::qglviewer::Vec ¢er) const { // Draw the axis - QGLViewer* viewerB = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewerB = *CGAL::QGLViewer::QGLViewerPool().begin(); if(frame == viewerB->manipulatedFrame()) { GLfloat f_matrix[16]; @@ -1528,7 +1529,7 @@ void Scene_edit_polyhedron_item_priv::draw_ROI_and_control_vertices(CGAL::Three: program->release(); item->vaos[Axis]->release(); - //QGLViewer::drawAxis(length_of_axis); + //CGAL::QGLViewer::drawAxis(length_of_axis); // draw bbox if(!ui_widget->ActivatePivotingCheckBox->isChecked()) { @@ -1765,7 +1766,7 @@ void Scene_edit_polyhedron_item::setVisible(bool b) { d->sm_item->setVisible(b); Scene_item::setVisible(b); if(!b) { - (*QGLViewer::QGLViewerPool().begin())->setManipulatedFrame(NULL); + (*CGAL::QGLViewer::QGLViewerPool().begin())->setManipulatedFrame(NULL); } } void Scene_edit_polyhedron_item::setColor(QColor c) { @@ -1831,8 +1832,8 @@ bool Scene_edit_polyhedron_item::keyPressEvent(QKeyEvent* e) { d->is_rot_free = !d->is_rot_free; d->rot_constraint.setRotationConstraintType( d->is_rot_free? - qglviewer::AxisPlaneConstraint::FREE: - qglviewer::AxisPlaneConstraint::AXIS); + CGAL::qglviewer::AxisPlaneConstraint::FREE: + CGAL::qglviewer::AxisPlaneConstraint::AXIS); return true; } @@ -2058,8 +2059,8 @@ void Scene_edit_polyhedron_item::create_ctrl_vertices_group() } } // No empty group of control vertices - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); - qglviewer::ManipulatedFrame* new_frame = new qglviewer::ManipulatedFrame(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); + CGAL::qglviewer::ManipulatedFrame* new_frame = new CGAL::qglviewer::ManipulatedFrame(); new_frame->setPosition(offset); new_frame->setRotationSensitivity(2.0f); connect(new_frame, SIGNAL(manipulated()), this, SLOT(change())); @@ -2197,11 +2198,11 @@ void Scene_edit_polyhedron_item_priv::pivoting_end(Mesh* mesh) for(typename std::list >::iterator it = fs.get_ctrl_vertex_frame_map(mesh).begin(); it != fs.get_ctrl_vertex_frame_map(mesh).end(); ++it) { //update constraint rotation vector, set only for the last group - it->rot_direction = it->frame->rotation().rotate( qglviewer::Vec(0.,0.,1.) ); + it->rot_direction = it->frame->rotation().rotate( CGAL::qglviewer::Vec(0.,0.,1.) ); //translate center of the frame - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); - qglviewer::Vec vec= it->frame->position(); - qglviewer::Quaternion orientation = it->frame->orientation(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); + CGAL::qglviewer::Vec vec= it->frame->position(); + CGAL::qglviewer::Quaternion orientation = it->frame->orientation(); it->refresh(mesh); it->frame_initial_center = vec-offset; it->frame->setPosition(vec); @@ -2214,8 +2215,8 @@ template void Scene_edit_polyhedron_item_priv::pivoting_begin(Mesh* mesh) { is_rot_free=true; - rot_constraint.setRotationConstraintType(qglviewer::AxisPlaneConstraint::FREE); - rot_constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::FREE); + rot_constraint.setRotationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FREE); + rot_constraint.setTranslationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FREE); // just block signals to prevent deformation Facegraph_selector fs(this); @@ -2456,11 +2457,11 @@ bool Scene_edit_polyhedron_item::activate_closest_manipulated_frame(int x, int y } if(fs.get_ctrl_vertex_frame_map(mesh).empty()) { return false; } - d->rot_constraint.setRotationConstraintType(qglviewer::AxisPlaneConstraint::FREE); - d->rot_constraint.setTranslationConstraintType(qglviewer::AxisPlaneConstraint::FREE); + d->rot_constraint.setRotationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FREE); + d->rot_constraint.setTranslationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FREE); - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); - qglviewer::Camera* camera = viewer->camera(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); + CGAL::qglviewer::Camera* camera = viewer->camera(); if(!d->state.ctrl_pressing) { @@ -2472,12 +2473,12 @@ bool Scene_edit_polyhedron_item::activate_closest_manipulated_frame(int x, int y // now find closest frame and make it active manipulated frame typename std::list >::iterator min_it = fs.get_ctrl_vertex_frame_map(mesh).begin(); - const qglviewer::Vec& pos_it = camera->projectedCoordinatesOf(min_it->frame->position()); + const CGAL::qglviewer::Vec& pos_it = camera->projectedCoordinatesOf(min_it->frame->position()); float min_dist = std::pow(pos_it.x - x, 2) + std::pow(pos_it.y - y, 2); for(typename std::list >::iterator it = fs.get_ctrl_vertex_frame_map(mesh).begin(); it != fs.get_ctrl_vertex_frame_map(mesh).end(); ++it) { - const qglviewer::Vec& pos_it = camera->projectedCoordinatesOf(it->frame->position()); + const CGAL::qglviewer::Vec& pos_it = camera->projectedCoordinatesOf(it->frame->position()); float dist = std::pow(pos_it.x - x, 2) + std::pow(pos_it.y - y, 2); if(dist < min_dist) { min_dist = dist; @@ -2488,7 +2489,7 @@ bool Scene_edit_polyhedron_item::activate_closest_manipulated_frame(int x, int y //set rotation constraint for the manipulated frame if (!d->is_rot_free){ d->rot_constraint.setRotationConstraintDirection(min_it->rot_direction); - d->rot_constraint.setRotationConstraintType(qglviewer::AxisPlaneConstraint::AXIS); + d->rot_constraint.setRotationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::AXIS); min_it->frame->setConstraint(&d->rot_constraint); } else @@ -2496,9 +2497,9 @@ bool Scene_edit_polyhedron_item::activate_closest_manipulated_frame(int x, int y if( d->ui_widget->ActivateFixedPlaneCheckBox->isChecked()) { // the constraint is local to the frame - d->rot_constraint.setTranslationConstraint(qglviewer::AxisPlaneConstraint::PLANE,qglviewer::Vec(0,0,1)); + d->rot_constraint.setTranslationConstraint(CGAL::qglviewer::AxisPlaneConstraint::PLANE,CGAL::qglviewer::Vec(0,0,1)); if(!d->ui_widget->ActivatePivotingCheckBox->isChecked()){ - d->rot_constraint.setRotationConstraintType(qglviewer::AxisPlaneConstraint::FORBIDDEN); + d->rot_constraint.setRotationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FORBIDDEN); } min_it->frame->setConstraint(&d->rot_constraint); } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.h b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.h index 5646c8c5da0..a5eaf6a28d5 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh_deformation/Scene_edit_polyhedron_item.h @@ -19,9 +19,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include "ui_Deform_mesh.h" @@ -162,9 +162,6 @@ typedef CGAL::Surface_mesh_deformation > Deform_sm_mesh; -typedef Deform_mesh::Point Point; -typedef Deform_sm_mesh::Point SM_Point; - /// For storing associated data with a group of control vertices template class Control_vertices_data @@ -176,16 +173,16 @@ public: Array_based_vertex_point_map > M_Deform_mesh; std::vector ctrl_vertices_group; - qglviewer::ManipulatedFrame* frame; // manframe assoc with a group of control vertices - qglviewer::Vec frame_initial_center; // initial center of frame + CGAL::qglviewer::ManipulatedFrame* frame; // manframe assoc with a group of control vertices + CGAL::qglviewer::Vec frame_initial_center; // initial center of frame CGAL::Three::Scene_interface::Bbox bbox; // bbox of control vertices inside group - qglviewer::Vec rot_direction; // vector for constraint rotation + CGAL::qglviewer::Vec rot_direction; // vector for constraint rotation private: - std::vector initial_positions; + std::vector initial_positions; M_Deform_mesh* deform_mesh; public: - Control_vertices_data(M_Deform_mesh* deform_mesh, qglviewer::ManipulatedFrame* frame = 0) + Control_vertices_data(M_Deform_mesh* deform_mesh, CGAL::qglviewer::ManipulatedFrame* frame = 0) : frame(frame), bbox(0,0,0,0,0,0), rot_direction(0.,0.,1.), deform_mesh(deform_mesh) { } @@ -204,30 +201,30 @@ public: bool oldState = frame->blockSignals(true); // do not let it Q_EMIT modified, which will cause a deformation // but we are just adjusting the center so it does not require a deformation - frame->setOrientation(qglviewer::Quaternion()); - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + frame->setOrientation(CGAL::qglviewer::Quaternion()); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); frame->setPosition(frame_initial_center+offset); frame->blockSignals(oldState); } void set_target_positions() { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); typename std::vector::iterator hb = ctrl_vertices_group.begin(); - for( std::vector::iterator it = initial_positions.begin(); it != initial_positions.end(); ++it, ++hb) + for( std::vector::iterator it = initial_positions.begin(); it != initial_positions.end(); ++it, ++hb) { - qglviewer::Vec dif_from_initial_center = (*it) - frame_initial_center; - qglviewer::Vec rotated = frame->orientation() * dif_from_initial_center; - qglviewer::Vec rotated_and_translated = rotated + frame->position(); + CGAL::qglviewer::Vec dif_from_initial_center = (*it) - frame_initial_center; + CGAL::qglviewer::Vec rotated = frame->orientation() * dif_from_initial_center; + CGAL::qglviewer::Vec rotated_and_translated = rotated + frame->position(); deform_mesh->set_target_position(*hb, typename M_Deform_mesh::Point(rotated_and_translated.x-offset.x, rotated_and_translated.y-offset.y, rotated_and_translated.z-offset.z) ); } } - qglviewer::Vec calculate_initial_center() const + CGAL::qglviewer::Vec calculate_initial_center() const { - qglviewer::Vec center_acc(0, 0, 0); + CGAL::qglviewer::Vec center_acc(0, 0, 0); if (initial_positions.empty()) { return center_acc; } - for (std::vector::const_iterator it = initial_positions.begin(); + for (std::vector::const_iterator it = initial_positions.begin(); it != initial_positions.end(); ++it) { center_acc += (*it); @@ -245,7 +242,7 @@ private: { typename M_Deform_mesh::Point p = get(pmap, (*hb)); - qglviewer::Vec point(p.x(), p.y(), p.z() ); + CGAL::qglviewer::Vec point(p.x(), p.y(), p.z() ); initial_positions.push_back(point); } } @@ -253,12 +250,12 @@ private: { if(initial_positions.empty()) {return CGAL::Three::Scene_interface::Bbox(0,0,0,0,0,0); } - const qglviewer::Vec& p_i = *(initial_positions.begin()); + const CGAL::qglviewer::Vec& p_i = *(initial_positions.begin()); CGAL::Three::Scene_interface::Bbox bbox(p_i.x, p_i.y, p_i.z, p_i.x, p_i.y, p_i.z); - for(std::vector::iterator it = initial_positions.begin(); it != initial_positions.end(); ++it) + for(std::vector::iterator it = initial_positions.begin(); it != initial_positions.end(); ++it) { - const qglviewer::Vec& p_i = (*it); + const CGAL::qglviewer::Vec& p_i = (*it); CGAL::Three::Scene_interface::Bbox bbox_it(p_i.x, p_i.y, p_i.z, p_i.x, p_i.y, p_i.z); bbox = bbox + bbox_it; } @@ -323,7 +320,7 @@ public: void draw_bbox(const CGAL::Three::Scene_interface::Bbox&) const; void draw_ROI_and_control_vertices(CGAL::Three::Viewer_interface *viewer) const; template - void draw_frame_plane(QGLViewer *, Mesh *mesh) const; + void draw_frame_plane(CGAL::QGLViewer *, Mesh *mesh) const; // Get wrapped polyhedron Polyhedron* polyhedron(); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_3.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_3.cpp index 2775bf4460d..0bb96d804da 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_3.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_3.cpp @@ -1,6 +1,6 @@ #include "Polyhedron_demo.h" #include - +#include /*! * \brief Defines the entry point of the demo. * Creates the application and sets a main window. diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_plugin_helper.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_plugin_helper.cpp index 0883de288cf..0418d405f72 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_plugin_helper.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_plugin_helper.cpp @@ -8,7 +8,7 @@ void CGAL::Three::Polyhedron_demo_plugin_helper::addDockWidget(QDockWidget* dock_widget) { mw->addDockWidget(::Qt::LeftDockWidgetArea, dock_widget); - dock_widget->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed)); + dock_widget->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); QList dockWidgets = mw->findChildren(); int counter = 0; diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index d18fce27ed7..48545a07753 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include @@ -234,7 +234,7 @@ Q_SIGNALS: private Q_SLOTS: // Casts a selection ray and calls the item function select. void setSelectionRay(double, double, double, double, double, double); - void callDraw(){ QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); viewer->update();} + void callDraw(){ CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); viewer->update();} void s_itemAboutToBeDestroyed(CGAL::Three::Scene_item *); private: /*! Calls the drawing functions of each visible item according diff --git a/Polyhedron/demo/Polyhedron/Scene_c2t3_item.cpp b/Polyhedron/demo/Polyhedron/Scene_c2t3_item.cpp deleted file mode 100644 index 9f35fd7180e..00000000000 --- a/Polyhedron/demo/Polyhedron/Scene_c2t3_item.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "Scene_c2t3_item.h" - diff --git a/Polyhedron/demo/Polyhedron/Scene_c2t3_item.h b/Polyhedron/demo/Polyhedron/Scene_c2t3_item.h deleted file mode 100644 index a420ca15156..00000000000 --- a/Polyhedron/demo/Polyhedron/Scene_c2t3_item.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef SCENE_C2T3_ITEM_H -#define SCENE_C2T3_ITEM_H - -#include "Scene_c2t3_item_config.h" -#include "C2t3_type.h" -#include -#include -#include -#include - -class SCENE_C2T3_ITEM_EXPORT Scene_c2t3_item : public CGAL::Three::Scene_item -{ - Q_OBJECT -public: - Scene_c2t3_item(const C2t3& c2t3) - : c2t3_(c2t3) - { - } - - ~Scene_c2t3_item() - { - } - - C2t3& c2t3() { - return c2t3_; - } - - const C2t3& c2t3() const { - return c2t3_; - } - bool isFinite() const { return true; } - bool isEmpty() const { - return c2t3().triangulation().number_of_vertices() == 0; - } - - void compute_bbox() const { - if(isEmpty()) - _bbox = Bbox(); - else { - bool first = true; - CGAL::Bbox_3 result; - for(Tr::Finite_vertices_iterator - vit = ++c2t3().triangulation().finite_vertices_begin(), - end = c2t3().triangulation().finite_vertices_end(); - vit != end; ++vit) - { - if(first) { - result = vit->point().bbox(); - first = false; - } else { - result = result + vit->point().bbox(); - } - } - _bbox = Bbox(result.xmin(), result.ymin(), result.zmin(), - result.xmax(), result.ymax(), result.zmax()); - } - } - - - Scene_c2t3_item* clone() const { - return 0; - } - - QString toolTip() const { - return tr("

2D complex in a 3D triangulation

" - "

Number of vertices: %1
" - "Number of surface facets: %2
") - .arg(c2t3().triangulation().number_of_vertices()) - .arg(c2t3().number_of_facets()); - } - - // Indicate if rendering mode is supported - bool supportsRenderingMode(RenderingMode m) const { - return (m != Gouraud && m!=PointsPlusNormals && m!=ShadedPoints); // CHECK THIS! - } - - void draw() const { - /* ::glBegin(GL_TRIANGLES); - for(C2t3::Facet_iterator - fit = c2t3().facets_begin(), - end = c2t3().facets_end(); - fit != end; ++fit) - { - const Tr::Cell_handle& cell = fit->first; - const int& index = fit->second; - const Tr::Geom_traits::Point_3& pa = cell->vertex((index+1)&3)->point(); - const Tr::Geom_traits::Point_3& pb = cell->vertex((index+2)&3)->point(); - const Tr::Geom_traits::Point_3& pc = cell->vertex((index+3)&3)->point(); - draw_triangle(pa, pb, pc); - } - ::glEnd();*/ - } - -private: - static void draw_triangle(const Tr::Point& pa, - const Tr::Point& pb, - const Tr::Point& pc) { - Tr::Geom_traits::Vector_3 n = cross_product(pb - pa, pc -pa); - n = n / CGAL::sqrt(n*n); - ::glNormal3d(n.x(),n.y(),n.z()); - - ::glVertex3d(pa.x(),pa.y(),pa.z()); - ::glVertex3d(pb.x(),pb.y(),pb.z()); - ::glVertex3d(pc.x(),pc.y(),pc.z()); - } - -private: - C2t3 c2t3_; -}; - -#endif // SCENE_C2T3_ITEM diff --git a/Polyhedron/demo/Polyhedron/Scene_c2t3_item_config.h b/Polyhedron/demo/Polyhedron/Scene_c2t3_item_config.h deleted file mode 100644 index dd221d91d7c..00000000000 --- a/Polyhedron/demo/Polyhedron/Scene_c2t3_item_config.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef SCENE_C2T3_ITEM_CONFIG_H -#define SCENE_C2T3_ITEM_CONFIG_H - -#ifdef scene_c2t3_item_EXPORTS -# define SCENE_C2T3_ITEM_EXPORT Q_DECL_EXPORT -#else -# define SCENE_C2T3_ITEM_EXPORT Q_DECL_IMPORT -#endif - -#endif // SCENE_C2T3_ITEM_CONFIG_H diff --git a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp index 2cdb1967fd8..4e3eb0bd689 100644 --- a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.cpp @@ -18,8 +18,8 @@ #include #include -#include -#include +#include +#include #include #include @@ -170,7 +170,7 @@ public : void addTriangle(const Tr::Bare_point& pa, const Tr::Bare_point& pb, const Tr::Bare_point& pc, const CGAL::Color color) { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); Geom_traits::Vector_3 n = cross_product(pb - pa, pc - pa); n = n / CGAL::sqrt(n*n); @@ -260,7 +260,7 @@ private: struct Scene_c3t3_item_priv { - typedef qglviewer::ManipulatedFrame ManipulatedFrame; + typedef CGAL::qglviewer::ManipulatedFrame ManipulatedFrame; Scene_c3t3_item_priv(Scene_c3t3_item* item) : item(item), c3t3() , frame(new ManipulatedFrame()) @@ -436,7 +436,7 @@ struct Scene_c3t3_item_priv { Scene_c3t3_item* item; C3t3 c3t3; bool is_grid_shown; - qglviewer::ManipulatedFrame* frame; + CGAL::qglviewer::ManipulatedFrame* frame; bool need_changed; mutable bool are_intersection_buffers_filled; Scene_spheres_item *spheres; @@ -790,9 +790,11 @@ Scene_c3t3_item::build_histogram() // draw min value and max value - const int min_tr_width = static_cast(2 * (std::floor(min_value)*cell_width + left_margin)); - const int max_tr_width = static_cast( - 2 * ((histo_data.size() - std::floor(max_value))*cell_width + left_margin)); + const int min_tr_width = + static_cast(2 * (std::floor(min_value)*cell_width + left_margin)); + const int max_tr_width = + static_cast(2 * ((double(histo_data.size()) - + std::floor(max_value))*cell_width + left_margin)); const int tr_y = drawing_height + top_margin + text_margin; painter.setPen(get_histogram_color(min_value)); @@ -828,30 +830,30 @@ Scene_c3t3_item_priv::compute_color_map(const QColor& c) typedef Indices::size_type size_type; const size_type nb_domains = subdomain_indices_.size(); - size_type i = 0; + double i = 0; for (Indices::iterator it = subdomain_indices_.begin(), - end = subdomain_indices_.end(); it != end; ++it, ++i) + end = subdomain_indices_.end(); it != end; ++it, i += 1.) { - double hue = c.hueF() + 1. / nb_domains * i; + double hue = c.hueF() + 1. / double(nb_domains) * i; if (hue > 1) { hue -= 1.; } colors_subdomains[*it] = QColor::fromHsvF(hue, c.saturationF(), c.valueF()); } const size_type nb_patch_indices = surface_patch_indices_.size(); i = 0; for (Indices::iterator it = surface_patch_indices_.begin(), - end = surface_patch_indices_.end(); it != end; ++it, ++i) + end = surface_patch_indices_.end(); it != end; ++it, i += 1.) { - double hue = c.hueF() + 1. / nb_patch_indices * i; + double hue = c.hueF() + 1. / double(nb_patch_indices) * i; if (hue > 1) { hue -= 1.; } colors[*it] = QColor::fromHsvF(hue, c.saturationF(), c.valueF()); } } -Geom_traits::Plane_3 Scene_c3t3_item::plane(qglviewer::Vec offset) const +Geom_traits::Plane_3 Scene_c3t3_item::plane(CGAL::qglviewer::Vec offset) const { - const qglviewer::Vec& pos = d->frame->position() - offset; - const qglviewer::Vec& n = - d->frame->inverseTransformOf(qglviewer::Vec(0.f, 0.f, 1.f)); + const CGAL::qglviewer::Vec& pos = d->frame->position() - offset; + const CGAL::qglviewer::Vec& n = + d->frame->inverseTransformOf(CGAL::qglviewer::Vec(0.f, 0.f, 1.f)); return Geom_traits::Plane_3(n[0], n[1], n[2], -n * pos); } @@ -1074,7 +1076,7 @@ void Scene_c3t3_item_priv::draw_triangle(const Tr::Bare_point& pa, #undef darker Geom_traits::Vector_3 n = cross_product(pb - pa, pc - pa); n = n / CGAL::sqrt(n*n); - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); for (int i = 0; i<3; i++) { @@ -1109,7 +1111,7 @@ void Scene_c3t3_item_priv::draw_triangle_edges(const Tr::Bare_point& pa, const Tr::Bare_point& pc) const { #undef darker - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); positions_lines.push_back(pa.x()+offset.x); positions_lines.push_back(pa.y()+offset.y); positions_lines.push_back(pa.z()+offset.z); @@ -1140,7 +1142,7 @@ void Scene_c3t3_item_priv::draw_triangle_edges_cnc(const Tr::Bare_point& pa, const Tr::Bare_point& pc) const { #undef darker - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); positions_lines_not_in_complex.push_back(pa.x()+offset.x); positions_lines_not_in_complex.push_back(pa.y()+offset.y); positions_lines_not_in_complex.push_back(pa.z()+offset.z); @@ -1422,6 +1424,7 @@ void Scene_c3t3_item_priv::computeIntersection(const Primitive& facet) Geom_traits::Construct_point_3 wp2p = c3t3.triangulation().geom_traits().construct_point_3_object(); + typedef unsigned char UC; Tr::Cell_handle ch = facet.id().first; if(intersected_cells.find(ch) == intersected_cells.end()) { @@ -1432,7 +1435,7 @@ void Scene_c3t3_item_priv::computeIntersection(const Primitive& facet) const Tr::Bare_point& pc = wp2p(ch->vertex(2)->point()); const Tr::Bare_point& pd = wp2p(ch->vertex(3)->point()); - CGAL::Color color(c.red(), c.green(), c.blue()); + CGAL::Color color(UC(c.red()), UC(c.green()), UC(c.blue())); intersection->addTriangle(pb, pa, pc, color); intersection->addTriangle(pa, pb, pd, color); @@ -1452,7 +1455,7 @@ void Scene_c3t3_item_priv::computeIntersection(const Primitive& facet) QColor c = this->colors_subdomains[nh->subdomain_index()].light(50); - CGAL::Color color(c.red(), c.green(), c.blue()); + CGAL::Color color(UC(c.red()), UC(c.green()), UC(c.blue())); intersection->addTriangle(pb, pa, pc, color); intersection->addTriangle(pa, pb, pd, color); @@ -1479,7 +1482,7 @@ struct ComputeIntersection { void Scene_c3t3_item_priv::computeIntersections() { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); if(!is_aabb_tree_built) fill_aabb_tree(); positions_poly.clear(); @@ -1540,13 +1543,14 @@ void Scene_c3t3_item_priv::computeSpheres() c.setRgb(50,50,50,255); } - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); Tr::Bare_point center(wp2p(vit->point()).x() + offset.x, wp2p(vit->point()).y() + offset.y, wp2p(vit->point()).z() + offset.z); float radius = vit->point().weight() ; + typedef unsigned char UC; spheres->add_sphere(Geom_traits::Sphere_3(center, radius), - CGAL::Color(c.red(), c.green(), c.blue())); + CGAL::Color(UC(c.red()), UC(c.green()), UC(c.blue()))); } spheres->invalidateOpenGLBuffers(); } @@ -1568,7 +1572,7 @@ void Scene_c3t3_item_priv::computeElements() float x = (2 * (float)complex_diag()) / 10.0; float y = (2 * (float)complex_diag()) / 10.0; - for (int u = 0; u < 11; u++) + for (float u = 0; u < 11; u += 1.f) { positions_grid.push_back(-(float)complex_diag() + x* u); @@ -1579,7 +1583,7 @@ void Scene_c3t3_item_priv::computeElements() positions_grid.push_back((float)complex_diag()); positions_grid.push_back(0.0); } - for (int v = 0; v<11; v++) + for (float v = 0; v<11; v += 1.f) { positions_grid.push_back(-(float)complex_diag()); @@ -1654,7 +1658,7 @@ bool Scene_c3t3_item::load_binary(std::istream& is) { if(!CGAL::Mesh_3::load_binary_file(is, c3t3())) return false; if(is && d->frame == 0) { - d->frame = new qglviewer::ManipulatedFrame(); + d->frame = new CGAL::qglviewer::ManipulatedFrame(); } d->reset_cut_plane(); if(is.good()) { @@ -1672,8 +1676,8 @@ Scene_c3t3_item_priv::reset_cut_plane() { const float xcenter = static_cast((bbox.xmax()+bbox.xmin())/2.); const float ycenter = static_cast((bbox.ymax()+bbox.ymin())/2.); const float zcenter = static_cast((bbox.zmax()+bbox.zmin())/2.); - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); - qglviewer::Vec center(xcenter+offset.x, ycenter+offset.y, zcenter+offset.z); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); + CGAL::qglviewer::Vec center(xcenter+offset.x, ycenter+offset.y, zcenter+offset.z); frame->setPosition(center); } @@ -1774,7 +1778,7 @@ CGAL::Three::Scene_item::ManipulatedFrame* Scene_c3t3_item::manipulatedFrame() { } void Scene_c3t3_item::setPosition(float x, float y, float z) { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); d->frame->setPosition(x+offset.x, y+offset.y, z+offset.z); } @@ -1795,7 +1799,7 @@ void Scene_c3t3_item::copyProperties(Scene_item *item) Scene_c3t3_item* c3t3_item = qobject_cast(item); if(!c3t3_item) return; - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); d->frame->setPositionAndOrientation(c3t3_item->manipulatedFrame()->position() - offset, c3t3_item->manipulatedFrame()->orientation()); @@ -1818,7 +1822,7 @@ void Scene_c3t3_item::set_valid(bool b) } float Scene_c3t3_item::getShrinkFactor() const { - return d->tet_Slider->value()/100.0f; + return float(d->tet_Slider->value())/100.0f; } bool Scene_c3t3_item::keyPressEvent(QKeyEvent *event) { @@ -2072,7 +2076,7 @@ void Scene_c3t3_item::itemAboutToBeDestroyed(Scene_item *item) d->tree.clear(); if(d->frame) { - static_cast(QGLViewer::QGLViewerPool().first())->setManipulatedFrame(0); + static_cast(CGAL::QGLViewer::QGLViewerPool().first())->setManipulatedFrame(0); delete d->frame; d->frame = NULL; delete d->tet_Slider; diff --git a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h index 708e015cbf9..465a8c6fd16 100644 --- a/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_c3t3_item.h @@ -11,8 +11,8 @@ #include #include -#include -#include +#include +#include #include #include #include @@ -33,7 +33,7 @@ using namespace CGAL::Three; { Q_OBJECT public: - typedef qglviewer::ManipulatedFrame ManipulatedFrame; + typedef CGAL::qglviewer::ManipulatedFrame ManipulatedFrame; Scene_c3t3_item(); Scene_c3t3_item(const C3t3& c3t3); @@ -82,7 +82,7 @@ public: void setNormal(float x, float y, float z) ; - Geom_traits::Plane_3 plane(qglviewer::Vec offset = qglviewer::Vec(0,0,0)) const; + Geom_traits::Plane_3 plane(CGAL::qglviewer::Vec offset = CGAL::qglviewer::Vec(0,0,0)) const; bool isFinite() const Q_DECL_OVERRIDE { return true; } bool isEmpty() const Q_DECL_OVERRIDE { diff --git a/Polyhedron/demo/Polyhedron/Scene_image_item.cpp b/Polyhedron/demo/Polyhedron/Scene_image_item.cpp index 30cd07c309c..b0a3d2553ca 100644 --- a/Polyhedron/demo/Polyhedron/Scene_image_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_image_item.cpp @@ -34,6 +34,10 @@ public: double vy() const { return im_.vy(); } double vz() const { return im_.vz(); } + double tx() const { return im_.image()->tx; } + double ty() const { return im_.image()->ty; } + double tz() const { return im_.image()->tz; } + private: unsigned char non_null_neighbor_data(std::size_t i, std::size_t j, @@ -77,12 +81,12 @@ Image_accessor::Image_accessor(const Image& im, int dx, int dy, int dz) } } - int i=0; + double i=0; const double starting_hue = 45./360.; // magenta for ( std::map::iterator it = colors_.begin(), - end = colors_.end() ; it != end ; ++it, ++i ) + end = colors_.end() ; it != end ; ++it, i += 1.) { - double hue = starting_hue + 1./colors_.size() * i; + double hue = starting_hue + 1./double(colors_.size()) * i; if ( hue > 1. ) { hue -= 1.; } it->second = QColor::fromHsvF(hue, .75, .75); } @@ -202,9 +206,9 @@ add_to_normal(unsigned char v, { if ( 0 != v ) { - x += dx; - y += dy; - z += dz; + x += float(dx); + y += float(dy); + z += float(dz); } } @@ -296,9 +300,9 @@ Vertex_buffer_helper::push_color(std::size_t i, std::size_t j, std::size_t k) { const QColor& color = data_.vertex_color(i,j,k); if ( ! color.isValid() ) { return; } - colors_.push_back(color.red()/255.f); - colors_.push_back(color.green()/255.f); - colors_.push_back(color.blue()/255.f); + colors_.push_back(float(color.red())/255.f); + colors_.push_back(float(color.green())/255.f); + colors_.push_back(float(color.blue())/255.f); } void @@ -320,27 +324,26 @@ Vertex_buffer_helper::push_normal(std::size_t i, std::size_t j, std::size_t k) void Vertex_buffer_helper::push_vertex(std::size_t i, std::size_t j, std::size_t k) { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); indices_.insert(std::make_pair(compute_position(i,j,k), vertices_.size()/3)); //resize the "border vertices" - double di(i),dj(j),dk(k); + double di = double(i),dj = double(j),dk = double(k); if (di == 0) di = 0.5; if (dj == 0) dj = 0.5; if (dk == 0) dk = 0.5; - if (di == data_.xdim()) - di = data_.xdim()-0.5; - if (dj == data_.ydim()) - dj = data_.ydim()-0.5; - if (dk == data_.zdim()) - dk = data_.zdim()-0.5; + if (di == double(data_.xdim())) + di = double(data_.xdim())-0.5; + if (dj == double(data_.ydim())) + dj = double(data_.ydim())-0.5; + if (dk == double(data_.zdim())) + dk = double(data_.zdim())-0.5; - vertices_.push_back( (di - 0.5) * data_.vx()+offset.x); - vertices_.push_back( (dj - 0.5) * data_.vy()+offset.y); - vertices_.push_back( (dk - 0.5) * data_.vz()+offset.z); + vertices_.push_back( (di - 0.5) * data_.vx() + data_.tx()); + vertices_.push_back( (dj - 0.5) * data_.vy() + data_.ty()); + vertices_.push_back( (dk - 0.5) * data_.vz() + data_.tz()); } void @@ -423,7 +426,7 @@ struct Scene_image_item_priv { item = parent; v_box = new std::vector(); - is_ogl_4_3 = static_cast(QGLViewer::QGLViewerPool().first())->isOpenGL_4_3(); + is_ogl_4_3 = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->isOpenGL_4_3(); is_hidden = hidden; compile_shaders(); initializeBuffers(); @@ -675,12 +678,12 @@ Scene_image_item::compute_bbox() const if(!m_image) _bbox = Bbox(); else - _bbox = Bbox(0, - 0, - 0, - (m_image->xdim()-1) * m_image->vx(), - (m_image->ydim()-1) * m_image->vy(), - (m_image->zdim()-1) * m_image->vz()); + _bbox = Bbox(m_image->image()->tx, + m_image->image()->ty, + m_image->image()->tz, + m_image->image()->tx+(m_image->xdim()-1) * m_image->vx(), + m_image->image()->ty+(m_image->ydim()-1) * m_image->vy(), + m_image->image()->tz+(m_image->zdim()-1) * m_image->vz()); } void @@ -809,9 +812,9 @@ Scene_image_item_priv::draw_gl(Viewer_interface* viewer) const { vao[0].bind(); if(!is_ogl_4_3) - viewer->glDrawElements(GL_TRIANGLES, m_ibo->size()/sizeof(GLuint), GL_UNSIGNED_INT, 0); + viewer->glDrawElements(GL_TRIANGLES, GLsizei(m_ibo->size()/sizeof(GLuint)), GL_UNSIGNED_INT, 0); else - viewer->glDrawElements(GL_LINES_ADJACENCY, m_ibo->size()/sizeof(GLuint), GL_UNSIGNED_INT, 0); + viewer->glDrawElements(GL_LINES_ADJACENCY, GLsizei(m_ibo->size()/sizeof(GLuint)), GL_UNSIGNED_INT, 0); vao[0].release(); } rendering_program.release(); @@ -833,7 +836,7 @@ Scene_image_item_priv::ibo_size() const GLint nb_elts = m_ibo->size(); m_ibo->release(); - return nb_elts/sizeof(GLuint); + return GLint(nb_elts/sizeof(GLuint)); return 0; } @@ -845,7 +848,7 @@ void Scene_image_item::changed() void Scene_image_item_priv::draw_Bbox(Scene_item::Bbox bbox, std::vector *vertices) { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); vertices->push_back(bbox.xmin()+offset.x); vertices->push_back(bbox.ymin()+offset.y); vertices->push_back(bbox.zmin()+offset.z); diff --git a/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp b/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp index 19bad4faa82..6d13c3a400b 100644 --- a/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include "Color_ramp.h" #include @@ -39,9 +39,9 @@ struct Scene_implicit_function_item_priv { delete frame_; } - typedef qglviewer::Vec Point; + typedef CGAL::qglviewer::Vec Point; typedef std::pair Point_value; - typedef qglviewer::ManipulatedFrame ManipulatedFrame; + typedef CGAL::qglviewer::ManipulatedFrame ManipulatedFrame; void compute_min_max(); void initialize_buffers(CGAL::Three::Viewer_interface *viewer) const; void compute_vertices_and_texmap(void); @@ -272,7 +272,7 @@ void Scene_implicit_function_item_priv::compute_vertices_and_texmap(void) } //the Box { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); positions_cube.push_back(b.xmin()+offset.x); positions_cube.push_back(b.ymin()+offset.y); @@ -439,7 +439,7 @@ Scene_implicit_function_item::draw(CGAL::Three::Viewer_interface* viewer) const double offset_x = (bbox().xmin() + bbox().xmax()) / 2; double offset_y = (bbox().ymin() + bbox().ymax()) / 2; double offset_z = (bbox().zmin() + bbox().zmax()) / 2; - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); d->frame_->setPosition(offset_x+offset.x, offset_y+offset.y, offset_z+offset.z); d->frame_->setOrientation(1., 0, 0, 0); d->init = true; @@ -556,7 +556,7 @@ void Scene_implicit_function_item:: compute_function_grid() const { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); typedef CGAL::Simple_cartesian K; typedef K::Aff_transformation_3 Aff_transformation; typedef K::Point_3 Point_3; diff --git a/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.h b/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.h index aafdf8ea99d..84ee1307af8 100644 --- a/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_implicit_function_item.h @@ -6,7 +6,7 @@ #include "Scene_implicit_function_item_config.h" #include "implicit_functions/Implicit_function_interface.h" #include "Color_ramp.h" -#include +#include #include #define SCENE_IMPLICIT_GRID_SIZE 120 @@ -42,7 +42,7 @@ class SCENE_IMPLICIT_FUNCTION_ITEM_EXPORT Scene_implicit_function_item { Q_OBJECT - typedef qglviewer::ManipulatedFrame ManipulatedFrame; + typedef CGAL::qglviewer::ManipulatedFrame ManipulatedFrame; public: Scene_implicit_function_item(Implicit_function_interface*); diff --git a/Polyhedron/demo/Polyhedron/Scene_item.cpp b/Polyhedron/demo/Polyhedron/Scene_item.cpp index f06926366ec..c4cbea6d3d1 100644 --- a/Polyhedron/demo/Polyhedron/Scene_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_item.cpp @@ -19,7 +19,7 @@ CGAL::Three::Scene_item::Scene_item(int buffers_size, int vaos_size) vaos(vaos_size) { - QGLViewer::QGLViewerPool().first()->makeCurrent(); + CGAL::QGLViewer::QGLViewerPool().first()->makeCurrent(); is_bbox_computed = false; is_diag_bbox_computed = false; for(int i=0; igetShaderProgram(program_name)->setAttributeValue ("color_facets", - c.redF(), - c.greenF(), - c.blueF()); + GLfloat(c.redF()), + GLfloat(c.greenF()), + GLfloat(c.blueF())); } else if(program_name == PROGRAM_WITH_TEXTURED_EDGES) { if(is_selected) c = c.lighter(50); viewer->getShaderProgram(program_name)->setUniformValue ("color_lines", - QVector3D(c.redF(), c.greenF(), c.blueF())); + QVector3D(float(c.redF()), + float(c.greenF()), + float(c.blueF()))); } viewer->getShaderProgram(program_name)->release(); } @@ -202,7 +204,7 @@ void CGAL::Three::Scene_item::attribBuffers(CGAL::Three::Viewer_interface* viewe QOpenGLShaderProgram* CGAL::Three::Scene_item::getShaderProgram(int name, CGAL::Three::Viewer_interface * viewer) const { if(viewer == 0) - viewer = dynamic_cast(*QGLViewer::QGLViewerPool().begin()); + viewer = dynamic_cast(*CGAL::QGLViewer::QGLViewerPool().begin()); return viewer->getShaderProgram(name); } diff --git a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp index 17c7178a764..4714e39c8a3 100644 --- a/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_nef_polyhedron_item.cpp @@ -266,7 +266,7 @@ void Scene_nef_polyhedron_item_priv::compute_normals_and_vertices(void) const positions_points.resize(0); normals.resize(0); positions_lines.resize(0); - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); //The Facets { diff --git a/Polyhedron/demo/Polyhedron/Scene_plane_item.cpp b/Polyhedron/demo/Polyhedron/Scene_plane_item.cpp index 51e332b99e5..630f559f485 100644 --- a/Polyhedron/demo/Polyhedron/Scene_plane_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_plane_item.cpp @@ -84,7 +84,7 @@ void Scene_plane_item::compute_normals_and_vertices(void) const float x = (2*diag)/10.0; float y = (2*diag)/10.0; { - for(int u = 0; u < 11; u++) + for(float u = 0; u < 11; u += 1.f) { positions_lines.push_back(-diag + x* u); @@ -95,7 +95,7 @@ void Scene_plane_item::compute_normals_and_vertices(void) const positions_lines.push_back(diag ); positions_lines.push_back(0.0 ); } - for(int v=0; v<11; v++) + for(float v=0; v<11; v += 1.f) { positions_lines.push_back(-diag ); @@ -151,12 +151,12 @@ void Scene_plane_item::drawEdges(CGAL::Three::Viewer_interface* viewer)const void Scene_plane_item::flipPlane() { - qglviewer::Quaternion q; - qglviewer::Vec axis(0,1,0); + CGAL::qglviewer::Quaternion q; + CGAL::qglviewer::Vec axis(0,1,0); if(frame->orientation().axis() == axis) - q.setAxisAngle(qglviewer::Vec(1,0,0), M_PI); + q.setAxisAngle(CGAL::qglviewer::Vec(1,0,0), CGAL_PI); else - q.setAxisAngle(axis, M_PI); + q.setAxisAngle(axis, CGAL_PI); frame->rotate(q.normalized()); invalidateOpenGLBuffers(); Q_EMIT itemChanged(); @@ -186,8 +186,8 @@ Scene_plane_item* Scene_plane_item::clone() const { } QString Scene_plane_item::toolTip() const { - const qglviewer::Vec& pos = frame->position(); - const qglviewer::Vec& n = frame->inverseTransformOf(qglviewer::Vec(0.f, 0.f, 1.f)); + const CGAL::qglviewer::Vec& pos = frame->position(); + const CGAL::qglviewer::Vec& n = frame->inverseTransformOf(CGAL::qglviewer::Vec(0.f, 0.f, 1.f)); return tr("

%1 (mode: %2, color: %3)
") .arg(this->name()) @@ -209,10 +209,10 @@ QString Scene_plane_item::toolTip() const { .arg(manipulable?tr("true"):tr("false")); } -Plane_3 Scene_plane_item::plane(qglviewer::Vec offset) const { - const qglviewer::Vec& pos = frame->position() - offset; - const qglviewer::Vec& n = - frame->inverseTransformOf(qglviewer::Vec(0.f, 0.f, 1.f)); +Plane_3 Scene_plane_item::plane(CGAL::qglviewer::Vec offset) const { + const CGAL::qglviewer::Vec& pos = frame->position() - offset; + const CGAL::qglviewer::Vec& n = + frame->inverseTransformOf(CGAL::qglviewer::Vec(0.f, 0.f, 1.f)); return Plane_3(n[0], n[1], n[2], - n * pos); } @@ -228,7 +228,7 @@ void Scene_plane_item::setPosition(float x, float y, float z) { } void Scene_plane_item::setPosition(double x, double y, double z) { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); frame->setPosition((float)x+offset.x, (float)y+offset.y, (float)z+offset.z); } @@ -237,21 +237,21 @@ void Scene_plane_item::setNormal(float x, float y, float z) { if(normal == QVector3D(0,0,0)) return; QVector3D origin(0,0,1); - qglviewer::Quaternion q; + CGAL::qglviewer::Quaternion q; if(origin == normal) { return; } if(origin == -normal) { - q.setAxisAngle(qglviewer::Vec(0,1,0),M_PI); + q.setAxisAngle(CGAL::qglviewer::Vec(0,1,0),CGAL_PI); frame->setOrientation(q); return; } QVector3D cp = QVector3D::crossProduct(origin, normal); cp.normalize(); - q.setAxisAngle(qglviewer::Vec(cp.x(),cp.y(), cp.z()),acos(QVector3D::dotProduct(origin, normal)/(normal.length()*origin.length()))); + q.setAxisAngle(CGAL::qglviewer::Vec(cp.x(),cp.y(), cp.z()),acos(QVector3D::dotProduct(origin, normal)/(normal.length()*origin.length()))); frame->setOrientation(q.normalized()); } diff --git a/Polyhedron/demo/Polyhedron/Scene_plane_item.h b/Polyhedron/demo/Polyhedron/Scene_plane_item.h index c9733c7a24d..1a380983333 100644 --- a/Polyhedron/demo/Polyhedron/Scene_plane_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_plane_item.h @@ -7,8 +7,8 @@ #include "Scene_basic_objects_config.h" -#include -#include +#include +#include #include #include @@ -22,7 +22,7 @@ class SCENE_BASIC_OBJECTS_EXPORT Scene_plane_item { Q_OBJECT public: - typedef qglviewer::ManipulatedFrame ManipulatedFrame; + typedef CGAL::qglviewer::ManipulatedFrame ManipulatedFrame; Scene_plane_item(const CGAL::Three::Scene_interface* scene_interface); ~Scene_plane_item(); @@ -77,7 +77,7 @@ public: } virtual void draw(CGAL::Three::Viewer_interface*) const; virtual void drawEdges(CGAL::Three::Viewer_interface* viewer)const; - Plane_3 plane(qglviewer::Vec offset = qglviewer::Vec(0,0,0)) const; + Plane_3 plane(CGAL::qglviewer::Vec offset = CGAL::qglviewer::Vec(0,0,0)) const; public Q_SLOTS: virtual void invalidateOpenGLBuffers(); @@ -98,7 +98,7 @@ protected: const CGAL::Three::Scene_interface* scene; bool manipulable; bool can_clone; - qglviewer::ManipulatedFrame* frame; + CGAL::qglviewer::ManipulatedFrame* frame; enum VAOs { Facets = 0, diff --git a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp index 2a3a4ba7372..ec8292e670f 100644 --- a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include @@ -154,7 +154,7 @@ class Fill_buffers { std::vector& positions_lines; std::vector& positions_normals; bool has_normals; - const qglviewer::Vec offset; + const CGAL::qglviewer::Vec offset; double length; std::size_t size_p; std::size_t offset_normal_indices; @@ -164,7 +164,7 @@ public: std::vector& positions_lines, std::vector& positions_normals, bool has_normals, - const qglviewer::Vec offset, + const CGAL::qglviewer::Vec offset, double length, std::size_t offset_normal_indices = 0) : point_set (point_set) @@ -442,7 +442,7 @@ void Scene_points_with_normal_item_priv::initializeBuffers(CGAL::Three::Viewer_i void Scene_points_with_normal_item_priv::compute_normals_and_vertices() const { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); QApplication::setOverrideCursor(Qt::WaitCursor); positions_lines.resize(0); normals.resize(0); @@ -1052,7 +1052,7 @@ zoomToPosition(const QPoint &, CGAL::Three::Viewer_interface *viewer) const { if (point_set()->nb_selected_points() == 0) return; - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); // fit plane to triangles Point_set points; Bbox selected_points_bbox; @@ -1075,8 +1075,8 @@ zoomToPosition(const QPoint &, CGAL::Three::Viewer_interface *viewer) const center_of_mass.y() + offset.y, center_of_mass.z() + offset.z); - qglviewer::Quaternion new_orientation(qglviewer::Vec(0,0,-1), - qglviewer::Vec(-plane_normal.x(), -plane_normal.y(), -plane_normal.z())); + CGAL::qglviewer::Quaternion new_orientation(CGAL::qglviewer::Vec(0,0,-1), + CGAL::qglviewer::Vec(-plane_normal.x(), -plane_normal.y(), -plane_normal.z())); double max_side = (std::max)((std::max)(selected_points_bbox.xmax() - selected_points_bbox.xmin(), selected_points_bbox.ymax() - selected_points_bbox.ymin()), selected_points_bbox.zmax() - selected_points_bbox.zmin()); @@ -1086,7 +1086,7 @@ zoomToPosition(const QPoint &, CGAL::Three::Viewer_interface *viewer) const (viewer->camera()->fieldOfView()/2))); Kernel::Point_3 new_pos = centroid + factor*plane_normal ; - viewer->camera()->setSceneCenter(qglviewer::Vec(centroid.x(), + viewer->camera()->setSceneCenter(CGAL::qglviewer::Vec(centroid.x(), centroid.y(), centroid.z())); viewer->moveCameraToCoordinates(QString("%1 %2 %3 %4 %5 %6 %7").arg(new_pos.x()) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 2f1129d3bd9..e4a6b4eb931 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -248,6 +248,9 @@ typedef Polygon_soup::Polygon_3 Facet; void Scene_polygon_soup_item_priv::triangulate_polygon(Polygons_iterator pit, int polygon_id) const { + const CGAL::qglviewer::Vec off = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); + EPICK::Vector_3 offset(off.x,off.y,off.z); + //Computes the normal of the facet const Point_3& pa = soup->points[pit->at(0)]; const Point_3& pb = soup->points[pit->at(1)]; @@ -267,7 +270,7 @@ Scene_polygon_soup_item_priv::triangulate_polygon(Polygons_iterator pit, int pol do { FT::PointAndId pointId; - pointId.point = soup->points[pit->at(it)]; + pointId.point = soup->points[pit->at(it)]+offset; pointId.id = pit->at(it); pointIds.push_back(pointId); } while( ++it != it_end ); @@ -348,7 +351,7 @@ Scene_polygon_soup_item_priv::compute_normals_and_vertices() const{ QApplication::setOverrideCursor(Qt::WaitCursor); //get the vertices and normals - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); typedef Polygon_soup::Polygons::size_type size_type; positions_poly.resize(0); diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp index d3aaf5de4ab..58a466c7ad1 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item.cpp @@ -163,7 +163,7 @@ struct Scene_polyhedron_item_priv{ void fillTargetedIds(const Polyhedron::Facet_handle& selected_fh, const Kernel::Point_3 &point_under, CGAL::Three::Viewer_interface *viewer, - const qglviewer::Vec &offset); + const CGAL::qglviewer::Vec &offset); Scene_polyhedron_item* item; Polyhedron *poly; double volume, area; @@ -411,7 +411,7 @@ void Scene_polyhedron_item_priv::triangulate_convex_facet(Facet_iterator f, const bool draw_two_sides, const bool is_recent)const { - const qglviewer::Vec v_offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec v_offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); Vector offset = Vector(v_offset.x, v_offset.y, v_offset.z); Polyhedron::Traits::Point_3 p0,p1,p2; Facet::Halfedge_around_facet_circulator @@ -473,14 +473,14 @@ Scene_polyhedron_item_priv::triangulate_facet(Scene_polyhedron_item::Facet_itera { typedef FacetTriangulator::vertex_descriptor> FT; - const qglviewer::Vec v_offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec v_offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); Vector offset = Vector(v_offset.x, v_offset.y, v_offset.z); double diagonal; if(item->diagonalBbox() != std::numeric_limits::infinity()) diagonal = item->diagonalBbox(); else diagonal = 0.0; - FT triangulation(fit,normal,poly,diagonal); + FT triangulation(fit,normal,poly,diagonal,offset); if(triangulation.cdt->dimension() != 2 ) { @@ -515,9 +515,9 @@ Scene_polyhedron_item_priv::triangulate_facet(Scene_polyhedron_item::Facet_itera if(is_multicolor || !no_flat || !is_recent) { - push_back_xyz(ffit->vertex(0)->point()+offset, positions_facets); - push_back_xyz(ffit->vertex(1)->point()+offset, positions_facets); - push_back_xyz(ffit->vertex(2)->point()+offset, positions_facets); + push_back_xyz(ffit->vertex(0)->point(), positions_facets); + push_back_xyz(ffit->vertex(1)->point(), positions_facets); + push_back_xyz(ffit->vertex(2)->point(), positions_facets); if(!draw_two_sides) { push_back_xyz(normal, normals_flat); @@ -697,7 +697,7 @@ Scene_polyhedron_item_priv::compute_normals_and_vertices(const bool is_recent, const bool draw_two_sides) const { bool add_flat_data = is_multicolor || (!is_recent || !no_flat); - const qglviewer::Vec v_offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec v_offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); QApplication::setOverrideCursor(Qt::WaitCursor); positions_facets.resize(0); @@ -914,7 +914,7 @@ Scene_polyhedron_item::Scene_polyhedron_item(const Polyhedron& p) Scene_polyhedron_item::~Scene_polyhedron_item() { delete_aabb_tree(this); - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); if(viewer) { CGAL::Three::Viewer_interface* v = qobject_cast(viewer); @@ -1177,7 +1177,7 @@ QMenu* Scene_polyhedron_item::contextMenu() actionEraseNextFacet->setObjectName("actionEraseNextFacet"); connect(actionEraseNextFacet, SIGNAL(toggled(bool)), this, SLOT(set_erase_next_picked_facet(bool))); - if(! static_cast(QGLViewer::QGLViewerPool().first())->isOpenGL_4_3()) + if(! static_cast(CGAL::QGLViewer::QGLViewerPool().first())->isOpenGL_4_3()) { QAction* actionDisableFlatShading= menu->addAction(tr("Disable Flat Shading")); @@ -1846,7 +1846,7 @@ void Scene_polyhedron_item::printPrimitiveId(QPoint point, CGAL::Three::Viewer_i return; Polyhedron::Facet_handle selected_fh; Kernel::Point_3 pt_under; - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); if(find_primitive_id(point, aabb_tree, viewer, selected_fh, pt_under)) d->fillTargetedIds(selected_fh, pt_under, viewer, offset); @@ -1854,7 +1854,7 @@ void Scene_polyhedron_item::printPrimitiveId(QPoint point, CGAL::Three::Viewer_i void Scene_polyhedron_item_priv::fillTargetedIds(const Polyhedron::Facet_handle& selected_fh, const Kernel::Point_3& pt_under, CGAL::Three::Viewer_interface *viewer, - const qglviewer::Vec& offset) + const CGAL::qglviewer::Vec& offset) { compute_displayed_ids(*poly, viewer, @@ -1915,7 +1915,7 @@ bool Scene_polyhedron_item::printFaceIds(CGAL::Three::Viewer_interface *viewer) void Scene_polyhedron_item_priv::killIds() { CGAL::Three::Viewer_interface* viewer = - qobject_cast(QGLViewer::QGLViewerPool().first()); + qobject_cast(CGAL::QGLViewer::QGLViewerPool().first()); deleteIds(viewer, textVItems, textEItems, @@ -1944,7 +1944,7 @@ void Scene_polyhedron_item::printAllIds(CGAL::Three::Viewer_interface *viewer) bool Scene_polyhedron_item::testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface* viewer)const { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); Kernel::Point_3 src(x - offset.x, y - offset.y, z - offset.z); @@ -2061,15 +2061,15 @@ void Scene_polyhedron_item::zoomToPosition(const QPoint &point, CGAL::Three::Vie Tree* aabb_tree = static_cast(d->get_aabb_tree()); if(aabb_tree) { - const qglviewer::Vec offset = - static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = + static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); //find clicked facet bool found = false; const Kernel::Point_3 ray_origin(viewer->camera()->position().x - offset.x, viewer->camera()->position().y - offset.y, viewer->camera()->position().z - offset.z); - qglviewer::Vec point_under = viewer->camera()->pointUnderPixel(point,found); - qglviewer::Vec dir = point_under - viewer->camera()->position(); + CGAL::qglviewer::Vec point_under = viewer->camera()->pointUnderPixel(point,found); + CGAL::qglviewer::Vec dir = point_under - viewer->camera()->position(); const Kernel::Vector_3 ray_dir(dir.x, dir.y, dir.z); const Kernel::Ray_3 ray(ray_origin, ray_dir); typedef std::list Intersections; @@ -2138,8 +2138,8 @@ void Scene_polyhedron_item::zoomToPosition(const QPoint &point, CGAL::Three::Vie y/total + offset.y, z/total + offset.z); - qglviewer::Quaternion new_orientation(qglviewer::Vec(0,0,-1), - qglviewer::Vec(-face_normal.x(), -face_normal.y(), -face_normal.z())); + CGAL::qglviewer::Quaternion new_orientation(CGAL::qglviewer::Vec(0,0,-1), + CGAL::qglviewer::Vec(-face_normal.x(), -face_normal.y(), -face_normal.z())); double max_side = (std::max)((std::max)(xmax-xmin, ymax-ymin), zmax-zmin); //put the camera in way we are sure the longest side is entirely visible on the screen @@ -2148,7 +2148,7 @@ void Scene_polyhedron_item::zoomToPosition(const QPoint &point, CGAL::Three::Vie (viewer->camera()->fieldOfView()/2)))); Kernel::Point_3 new_pos = centroid + factor*face_normal ; - viewer->camera()->setSceneCenter(qglviewer::Vec(centroid.x(), + viewer->camera()->setSceneCenter(CGAL::qglviewer::Vec(centroid.x(), centroid.y(), centroid.z())); viewer->moveCameraToCoordinates(QString("%1 %2 %3 %4 %5 %6 %7").arg(new_pos.x()) @@ -2174,7 +2174,7 @@ void Scene_polyhedron_item::resetColors() void Scene_polyhedron_item::showVertices(bool b) { CGAL::Three::Viewer_interface* viewer = - qobject_cast(QGLViewer::QGLViewerPool().first()); + qobject_cast(CGAL::QGLViewer::QGLViewerPool().first()); TextRenderer *renderer = viewer->textRenderer(); if(b) if(d->textVItems->isEmpty()) @@ -2193,7 +2193,7 @@ void Scene_polyhedron_item::showVertices(bool b) void Scene_polyhedron_item::showEdges(bool b) { CGAL::Three::Viewer_interface* viewer = - qobject_cast(QGLViewer::QGLViewerPool().first()); + qobject_cast(CGAL::QGLViewer::QGLViewerPool().first()); TextRenderer *renderer = viewer->textRenderer(); if(b) if(d->textEItems->isEmpty()) @@ -2212,7 +2212,7 @@ void Scene_polyhedron_item::showEdges(bool b) void Scene_polyhedron_item::showFaces(bool b) { CGAL::Three::Viewer_interface* viewer = - qobject_cast(QGLViewer::QGLViewerPool().first()); + qobject_cast(CGAL::QGLViewer::QGLViewerPool().first()); TextRenderer *renderer = viewer->textRenderer(); if(b) { @@ -2233,7 +2233,7 @@ void Scene_polyhedron_item::showFaces(bool b) void Scene_polyhedron_item::showPrimitives(bool) { CGAL::Three::Viewer_interface* viewer = - qobject_cast(QGLViewer::QGLViewerPool().first()); + qobject_cast(CGAL::QGLViewer::QGLViewerPool().first()); printAllIds(viewer); } void Scene_polyhedron_item::zoomToId() @@ -2247,7 +2247,7 @@ void Scene_polyhedron_item::zoomToId() return; CGAL::Three::Viewer_interface* viewer = - qobject_cast(QGLViewer::QGLViewerPool().first()); + qobject_cast(CGAL::QGLViewer::QGLViewerPool().first()); Point p; QString id = text.right(text.length()-1); int return_value = ::zoomToId(*d->poly, text, viewer, selected_fh, p); diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item_k_ring_selection.h b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item_k_ring_selection.h index ae28c92a568..9db47fbe5a8 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_item_k_ring_selection.h +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_item_k_ring_selection.h @@ -5,7 +5,7 @@ #include "Scene_polyhedron_item.h" #include "Scene_surface_mesh_item.h" -#include +#include #include #include #include @@ -101,7 +101,7 @@ public: void setEditMode(bool b) { is_edit_mode = b; - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); //for highlighting viewer->setMouseTracking(b); } @@ -123,14 +123,10 @@ public: poly_item->enable_facets_picking(true); poly_item->set_color_vector_read_only(true); } - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); viewer->installEventFilter(this); mw->installEventFilter(this); -#if QGLVIEWER_VERSION >= 0x020501 viewer->setMouseBindingDescription(Qt::Key_D, Qt::ShiftModifier, Qt::LeftButton, "(When in selection plugin) Removes the clicked primitive from the selection. "); -#else - viewer->setMouseBindingDescription(Qt::SHIFT + Qt::LeftButton, "(When in selection plugin) When D is pressed too, removes the clicked primitive from the selection. "); -#endif if(poly_item) { connect(poly_item, SIGNAL(selected_vertex(void*)), this, SLOT(vertex_has_been_selected(void*))); @@ -222,18 +218,18 @@ public Q_SLOTS: { if(is_ready_to_paint_select) { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); // paint with mouse move event - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); - qglviewer::Camera* camera = viewer->camera(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); + CGAL::qglviewer::Camera* camera = viewer->camera(); viewer->makeCurrent(); bool found = false; - const qglviewer::Vec& point = camera->pointUnderPixel(paint_pos, found) - offset; + const CGAL::qglviewer::Vec& point = camera->pointUnderPixel(paint_pos, found) - offset; if(found) { - const qglviewer::Vec& orig = camera->position() - offset; - const qglviewer::Vec& dir = point - orig; + const CGAL::qglviewer::Vec& orig = camera->position() - offset; + const CGAL::qglviewer::Vec& dir = point - orig; if(poly_item) poly_item->select(orig.x, orig.y, orig.z, dir.x, dir.y, dir.z); else @@ -247,10 +243,10 @@ public Q_SLOTS: { if(!poly_item) return; - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); - const qglviewer::Vec offset = static_cast(viewer)->offset(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); + const CGAL::qglviewer::Vec offset = static_cast(viewer)->offset(); - qglviewer::Camera* camera = viewer->camera(); + CGAL::qglviewer::Camera* camera = viewer->camera(); const Polyhedron& poly = *poly_item->polyhedron(); std::set face_sel; @@ -259,8 +255,8 @@ public Q_SLOTS: { BOOST_FOREACH(poly_vertex_descriptor v, CGAL::vertices_around_face(f->halfedge(), poly)) { - qglviewer::Vec vp(v->point().x(), v->point().y(), v->point().z()); - qglviewer::Vec vsp = camera->projectedCoordinatesOf(vp+offset); + CGAL::qglviewer::Vec vp(v->point().x(), v->point().y(), v->point().z()); + CGAL::qglviewer::Vec vsp = camera->projectedCoordinatesOf(vp+offset); if(is_vertex_selected(vsp)) { face_sel.insert(f); @@ -314,9 +310,9 @@ public Q_SLOTS: } if(total == 0) continue; - qglviewer::Vec center(x/(double)total, y/(double)total, z/(double)total); - const qglviewer::Vec& orig = camera->position() - offset; - qglviewer::Vec direction = center - orig; + CGAL::qglviewer::Vec center(x/(double)total, y/(double)total, z/(double)total); + const CGAL::qglviewer::Vec& orig = camera->position() - offset; + CGAL::qglviewer::Vec direction = center - orig; if(poly_item->intersect_face(orig.x, orig.y, orig.z, @@ -346,11 +342,11 @@ public Q_SLOTS: BOOST_FOREACH(poly_halfedge_descriptor h, CGAL::halfedges_around_face(halfedge(f,poly), poly)) { poly_vertex_descriptor vd = target(h,poly); - qglviewer::Vec vp1(vd->point().x(), vd->point().y(), vd->point().z()); - qglviewer::Vec vsp1 = camera->projectedCoordinatesOf(vp1+offset); + CGAL::qglviewer::Vec vp1(vd->point().x(), vd->point().y(), vd->point().z()); + CGAL::qglviewer::Vec vsp1 = camera->projectedCoordinatesOf(vp1+offset); vd = source(h,poly); - qglviewer::Vec vp2(vd->point().x(), vd->point().y(), vd->point().z()); - qglviewer::Vec vsp2 = camera->projectedCoordinatesOf(vp2+offset); + CGAL::qglviewer::Vec vp2(vd->point().x(), vd->point().y(), vd->point().z()); + CGAL::qglviewer::Vec vsp2 = camera->projectedCoordinatesOf(vp2+offset); if(is_vertex_selected(vsp1) || is_vertex_selected(vsp2)) e_sel.insert(edge(h, poly)); } @@ -365,8 +361,8 @@ public Q_SLOTS: { BOOST_FOREACH(poly_vertex_descriptor v, CGAL::vertices_around_face(f->halfedge(), poly)) { - qglviewer::Vec vp(v->point().x(), v->point().y(), v->point().z()); - qglviewer::Vec vsp = camera->projectedCoordinatesOf(vp+offset); + CGAL::qglviewer::Vec vp(v->point().x(), v->point().y(), v->point().z()); + CGAL::qglviewer::Vec vsp = camera->projectedCoordinatesOf(vp+offset); if(is_vertex_selected(vsp)) v_sel.insert(v); } @@ -384,18 +380,18 @@ public Q_SLOTS: { if(!poly_item && !sm_item) return; - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); if(is_ready_to_highlight) { // highlight with mouse move event - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); - qglviewer::Camera* camera = viewer->camera(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); + CGAL::qglviewer::Camera* camera = viewer->camera(); bool found = false; - const qglviewer::Vec& point = camera->pointUnderPixel(hl_pos, found) - offset; + const CGAL::qglviewer::Vec& point = camera->pointUnderPixel(hl_pos, found) - offset; if(found) { - const qglviewer::Vec& orig = camera->position() - offset; - const qglviewer::Vec& dir = point - orig; + const CGAL::qglviewer::Vec& orig = camera->position() - offset; + const CGAL::qglviewer::Vec& dir = point - orig; is_highlighting = true; if(poly_item) poly_item->select(orig.x, orig.y, orig.z, dir.x, dir.y, dir.z); @@ -628,7 +624,7 @@ protected: return false; if(target == mainwindow) { - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); viewer->setFocus(); return false; } @@ -651,7 +647,7 @@ protected: { if(target == mainwindow) { - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); viewer->setFocus(); return false; } @@ -695,7 +691,7 @@ protected: void sample_mouse_path() { - CGAL::Three::Viewer_interface* viewer = static_cast(*QGLViewer::QGLViewerPool().begin()); + CGAL::Three::Viewer_interface* viewer = static_cast(*CGAL::QGLViewer::QGLViewerPool().begin()); viewer->makeCurrent(); const QPoint& p = viewer->mapFromGlobal(QCursor::pos()); contour_2d.push_back (Kernel::Point_2 (p.x(), p.y())); @@ -708,11 +704,7 @@ protected: pen.setColor(QColor(Qt::green)); pen.setWidth(3); //Create a QImage of the screen and paint the lasso on top of it -#if QGLVIEWER_VERSION >= 0x020700 QImage image = viewer->grabFramebuffer(); -#else - QImage image = viewer->grabFrameBuffer(); -#endif painter->begin(viewer); painter->drawImage(QPoint(0,0), image); painter->setPen(pen); @@ -735,7 +727,7 @@ protected: lasso = Polygon_2 (contour_2d.begin (), contour_2d.end ()); } - bool is_vertex_selected (qglviewer::Vec& p) + bool is_vertex_selected (CGAL::qglviewer::Vec& p) { if (domain_rectangle.xmin () < p.x && p.x < domain_rectangle.xmax () && diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp index 1336f57028a..6df22ab25e7 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp @@ -421,13 +421,16 @@ void Scene_polyhedron_selection_item_priv::triangulate_facet(fg_face_descriptor fit,const Vector normal, std::vector &p_facets,std::vector &p_normals ) const { + const CGAL::qglviewer::Vec off = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); + Kernel::Vector_3 offset(off.x,off.y,off.z); + typedef FacetTriangulator FT; double diagonal; if(item->poly_item->diagonalBbox() != std::numeric_limits::infinity()) diagonal = item->poly_item->diagonalBbox(); else diagonal = 0.0; - FT triangulation(fit,normal,poly,diagonal); + FT triangulation(fit,normal,poly,diagonal, offset); //iterates on the internal faces to add the vertices to the positions //and the normals to the appropriate vectors for(FT::CDT::Finite_faces_iterator @@ -452,7 +455,7 @@ Scene_polyhedron_selection_item_priv::triangulate_facet(fg_face_descriptor fit,c void Scene_polyhedron_selection_item_priv::compute_any_elements(std::vector& p_facets, std::vector& p_lines, std::vector& p_points, std::vector& p_normals, const Selection_set_vertex& p_sel_vertices, const Selection_set_facet& p_sel_facets, const Selection_set_edge& p_sel_edges)const { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); p_facets.clear(); p_lines.clear(); p_points.clear(); @@ -578,7 +581,7 @@ void Scene_polyhedron_selection_item_priv::compute_temp_elements()const item->temp_selected_vertices, item->temp_selected_facets, item->temp_selected_edges); //The fixed points { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); color_fixed_points.clear(); positions_fixed_points.clear(); int i=0; @@ -833,7 +836,7 @@ void Scene_polyhedron_selection_item::inverse_selection() } } invalidateOpenGLBuffers(); - QGLViewer* v = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* v = *CGAL::QGLViewer::QGLViewerPool().begin(); v->update(); } @@ -1105,8 +1108,8 @@ bool Scene_polyhedron_selection_item::treat_selection(const std::set(viewer)->offset(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); + const CGAL::qglviewer::Vec offset = static_cast(viewer)->offset(); if(viewer->manipulatedFrame() != d->manipulated_frame) { temp_selected_vertices.insert(vh); @@ -1828,7 +1831,7 @@ Scene_polyhedron_selection_item::Scene_polyhedron_selection_item() d = new Scene_polyhedron_selection_item_priv(this); d->original_sel_mode = static_cast(0); d->operation_mode = -1; - QGLViewer::QGLViewerPool().first()->makeCurrent(); + CGAL::QGLViewer::QGLViewerPool().first()->makeCurrent(); for(int i=0; i(v); viewer->setBindingSelect(); } @@ -1931,7 +1934,7 @@ void Scene_polyhedron_selection_item::add_to_selection() } on_Ctrlz_pressed(); invalidateOpenGLBuffers(); - QGLViewer* v = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* v = *CGAL::QGLViewer::QGLViewerPool().begin(); v->update(); d->tempInstructions("Path added to selection.", "Select two vertices to create the path between them. (1/2)"); @@ -1962,7 +1965,7 @@ void Scene_polyhedron_selection_item::moveVertex() { if(d->ready_to_move) { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); fg_vertex_descriptor vh = *temp_selected_vertices.begin(); VPmap vpm = get(CGAL::vertex_point,*polyhedron()); @@ -1978,7 +1981,7 @@ void Scene_polyhedron_selection_item::moveVertex() void Scene_polyhedron_selection_item::validateMoveVertex() { temp_selected_vertices.clear(); - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); k_ring_selector.setEditMode(true); viewer->setManipulatedFrame(NULL); invalidateOpenGLBuffers(); @@ -2166,7 +2169,7 @@ void Scene_polyhedron_selection_item::init(Scene_face_graph_item* poly_item, QMa connect(&k_ring_selector,SIGNAL(isCurrentlySelected(Scene_facegraph_item_k_ring_selection*)), this, SIGNAL(isCurrentlySelected(Scene_facegraph_item_k_ring_selection*))); k_ring_selector.init(poly_item, mw, Active_handle::VERTEX, -1); connect(&k_ring_selector, SIGNAL(resetIsTreated()), this, SLOT(resetIsTreated())); - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); d->manipulated_frame = new ManipulatedFrame(); viewer->installEventFilter(this); mw->installEventFilter(this); @@ -2184,7 +2187,7 @@ void Scene_polyhedron_selection_item::select_all_NT() void Scene_polyhedron_selection_item::selection_changed(bool b) { - QGLViewer* v = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* v = *CGAL::QGLViewer::QGLViewerPool().begin(); CGAL::Three::Viewer_interface* viewer = dynamic_cast(v); if(!viewer) return; @@ -2251,7 +2254,7 @@ void Scene_polyhedron_selection_item::select_boundary() QString Scene_polyhedron_selection_item::toolTip() const { - if(!poly_item->polyhedron()) + if(!poly_item || !poly_item->polyhedron()) return QString(); return QObject::tr("

Selection %1 (mode: %5, color: %6)

" diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.h b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.h index 32c4e6cbf01..0499955c4e8 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.h @@ -33,7 +33,7 @@ #include #include -#include +#include namespace PMP = CGAL::Polygon_mesh_processing; @@ -433,7 +433,7 @@ public: case Active_handle::PATH: selected_edges.insert(edges(*polyhedron()).first, edges(*polyhedron()).second); invalidateOpenGLBuffers(); - QGLViewer* v = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* v = *CGAL::QGLViewer::QGLViewerPool().begin(); v->update(); break; } diff --git a/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp index 2eee388b3f2..6565e39515f 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polylines_item.cpp @@ -96,7 +96,7 @@ Scene_polylines_item_private::initializeBuffers(CGAL::Three::Viewer_interface *v void Scene_polylines_item_private::computeElements() const { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); QApplication::setOverrideCursor(Qt::WaitCursor); positions_lines.resize(0); double mean = 0; @@ -139,7 +139,7 @@ Scene_polylines_item_private::computeElements() const } if(!computed_stats) - mean_length = mean/nb_edges; + mean_length = mean/double(nb_edges); computed_stats = true; QApplication::restoreOverrideCursor(); } @@ -147,7 +147,7 @@ Scene_polylines_item_private::computeElements() const void Scene_polylines_item_private::computeSpheres() { - const qglviewer::Vec v_offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec v_offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); K::Vector_3 offset(v_offset.x, v_offset.y, v_offset.z); spheres->clear_spheres(); @@ -211,7 +211,7 @@ Scene_polylines_item_private::computeSpheres() p_it != end; ++p_it) { const K::Point_3& center = p_it->first; - int colors[3]; + unsigned char colors[3]; switch(p_it->second) { case 1: colors[0] = 0; // black @@ -388,7 +388,7 @@ Scene_polylines_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const { d->initializeBuffers(viewer); } - viewer->glLineWidth(d->line_Slider->value()); + viewer->glLineWidth(GLfloat(d->line_Slider->value())); vaos[Scene_polylines_item_private::Edges]->bind(); attribBuffers(viewer, PROGRAM_NO_SELECTION); QOpenGLShaderProgram *program = getShaderProgram(PROGRAM_NO_SELECTION); diff --git a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp index 9dcf97dbe84..90ac461904f 100644 --- a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp @@ -116,7 +116,7 @@ struct Scene_surface_mesh_item_priv{ void fillTargetedIds(const face_descriptor& selected_fh, const EPICK::Point_3 &point_under, CGAL::Three::Viewer_interface *viewer, - const qglviewer::Vec &offset); + const CGAL::qglviewer::Vec &offset); void initialize_colors(); void invalidate_stats(); @@ -292,7 +292,7 @@ Scene_surface_mesh_item::color_vector() void Scene_surface_mesh_item_priv::addFlatData(Point p, EPICK::Vector_3 n, CGAL::Color *c) const { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); flat_vertices.push_back((cgal_gl_data)(p.x()+offset[0])); flat_vertices.push_back((cgal_gl_data)(p.y()+offset[1])); @@ -395,7 +395,7 @@ void Scene_surface_mesh_item_priv::compute_elements() } idx_edge_data_.shrink_to_fit(); - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); SMesh::Property_map positions = smesh_->points(); @@ -584,7 +584,7 @@ void Scene_surface_mesh_item_priv::initializeBuffers(CGAL::Three::Viewer_interfa //vao containing the data for the smooth facets item->vaos[Scene_surface_mesh_item_priv::Smooth_facets]->bind(); item->buffers[Scene_surface_mesh_item_priv::Smooth_vertices].bind(); - if(!(floated||viewer->offset() == qglviewer::Vec(0,0,0))) + if(!(floated||viewer->offset() == CGAL::qglviewer::Vec(0,0,0))) { item->buffers[Scene_surface_mesh_item_priv::Smooth_vertices].allocate(positions.data(), static_cast(num_vertices(*smesh_)*3*sizeof(cgal_gl_data))); @@ -815,7 +815,9 @@ Scene_surface_mesh_item_priv::triangulate_facet(face_descriptor fd, diagonal = item->diagonalBbox(); else diagonal = 0.0; - FT triangulation(fd,normal,smesh_,diagonal); + const CGAL::qglviewer::Vec off = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); + EPICK::Vector_3 offset(off.x,off.y,off.z); + FT triangulation(fd,normal,smesh_,diagonal, offset); //iterates on the internal faces for(FT::CDT::Finite_faces_iterator ffit = triangulation.cdt->finite_faces_begin(), @@ -834,14 +836,14 @@ Scene_surface_mesh_item_priv::triangulate_facet(face_descriptor fd, else color = 0; - addFlatData(ffit->vertex(0)->point(), + addFlatData(ffit->vertex(0)->point()-offset, (*fnormals)[fd], color); - addFlatData(ffit->vertex(1)->point(), + addFlatData(ffit->vertex(1)->point()-offset, (*fnormals)[fd], color); - addFlatData(ffit->vertex(2)->point(), + addFlatData(ffit->vertex(2)->point()-offset, (*fnormals)[fd], color); } @@ -872,7 +874,7 @@ void delete_aabb_tree(Scene_surface_mesh_item* item) Scene_surface_mesh_item::~Scene_surface_mesh_item() { delete_aabb_tree(this); - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); if(viewer) { CGAL::Three::Viewer_interface* v = qobject_cast(viewer); @@ -1554,14 +1556,26 @@ void Scene_surface_mesh_item::zoomToPosition(const QPoint &point, CGAL::Three::V Tree* aabb_tree = static_cast(d->get_aabb_tree()); if(aabb_tree) { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); //find clicked facet bool found = false; - const EPICK::Point_3 ray_origin(viewer->camera()->position().x - offset.x, - viewer->camera()->position().y - offset.y, - viewer->camera()->position().z - offset.z); - qglviewer::Vec point_under = viewer->camera()->pointUnderPixel(point,found); - qglviewer::Vec dir = point_under - viewer->camera()->position(); + CGAL::qglviewer::Vec point_under = viewer->camera()->pointUnderPixel(point,found); + EPICK::Point_3 ray_origin; + CGAL::qglviewer::Vec dir; + if(viewer->camera()->type() == CGAL::qglviewer::Camera::PERSPECTIVE) + { + ray_origin = EPICK::Point_3(viewer->camera()->position().x - offset.x, + viewer->camera()->position().y - offset.y, + viewer->camera()->position().z - offset.z); + dir = point_under - viewer->camera()->position(); + } + else + { + dir = viewer->camera()->viewDirection(); + ray_origin = EPICK::Point_3(point_under.x - dir.x, + point_under.y - dir.y, + point_under.z - dir.z); + } const EPICK::Vector_3 ray_dir(dir.x, dir.y, dir.z); const EPICK::Ray_3 ray(ray_origin, ray_dir); typedef std::list Intersections; @@ -1632,8 +1646,8 @@ void Scene_surface_mesh_item::zoomToPosition(const QPoint &point, CGAL::Three::V y/total + offset.y, z/total + offset.z); - qglviewer::Quaternion new_orientation(qglviewer::Vec(0,0,-1), - qglviewer::Vec(-face_normal.x(), -face_normal.y(), -face_normal.z())); + CGAL::qglviewer::Quaternion new_orientation(CGAL::qglviewer::Vec(0,0,-1), + CGAL::qglviewer::Vec(-face_normal.x(), -face_normal.y(), -face_normal.z())); double max_side = (std::max)((std::max)(xmax-xmin, ymax-ymin), zmax-zmin); //put the camera in way we are sure the longest side is entirely visible on the screen @@ -1642,7 +1656,7 @@ void Scene_surface_mesh_item::zoomToPosition(const QPoint &point, CGAL::Three::V (viewer->camera()->fieldOfView()/2)))); EPICK::Point_3 new_pos = centroid + factor*face_normal ; - viewer->camera()->setSceneCenter(qglviewer::Vec(centroid.x(), + viewer->camera()->setSceneCenter(CGAL::qglviewer::Vec(centroid.x(), centroid.y(), centroid.z())); viewer->moveCameraToCoordinates(QString("%1 %2 %3 %4 %5 %6 %7").arg(new_pos.x()) @@ -1738,7 +1752,7 @@ void Scene_surface_mesh_item::printPrimitiveId(QPoint point, CGAL::Three::Viewer return; face_descriptor selected_fh; EPICK::Point_3 pt_under; - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); if(find_primitive_id(point, aabb_tree, viewer, selected_fh, pt_under)) d->fillTargetedIds(selected_fh, pt_under, viewer, offset); @@ -1746,7 +1760,7 @@ void Scene_surface_mesh_item::printPrimitiveId(QPoint point, CGAL::Three::Viewer void Scene_surface_mesh_item_priv::fillTargetedIds(const face_descriptor &selected_fh, const EPICK::Point_3& pt_under, CGAL::Three::Viewer_interface *viewer, - const qglviewer::Vec& offset) + const CGAL::qglviewer::Vec& offset) { compute_displayed_ids(*smesh_, viewer, @@ -1807,7 +1821,7 @@ bool Scene_surface_mesh_item::printFaceIds(CGAL::Three::Viewer_interface *viewer void Scene_surface_mesh_item_priv::killIds() { CGAL::Three::Viewer_interface* viewer = - qobject_cast(QGLViewer::QGLViewerPool().first()); + qobject_cast(CGAL::QGLViewer::QGLViewerPool().first()); deleteIds(viewer, textVItems, textEItems, @@ -1836,7 +1850,7 @@ void Scene_surface_mesh_item::printAllIds(CGAL::Three::Viewer_interface *viewer) bool Scene_surface_mesh_item::testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface* viewer)const { - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); EPICK::Point_3 src(x - offset.x, y - offset.y, z - offset.z); @@ -1855,7 +1869,7 @@ bool Scene_surface_mesh_item::testDisplayId(double x, double y, double z, CGAL:: void Scene_surface_mesh_item::showVertices(bool b) { CGAL::Three::Viewer_interface* viewer = - qobject_cast(QGLViewer::QGLViewerPool().first()); + qobject_cast(CGAL::QGLViewer::QGLViewerPool().first()); TextRenderer *renderer = viewer->textRenderer(); if(b) if(d->textVItems->isEmpty()) @@ -1874,7 +1888,7 @@ void Scene_surface_mesh_item::showVertices(bool b) void Scene_surface_mesh_item::showEdges(bool b) { CGAL::Three::Viewer_interface* viewer = - qobject_cast(QGLViewer::QGLViewerPool().first()); + qobject_cast(CGAL::QGLViewer::QGLViewerPool().first()); TextRenderer *renderer = viewer->textRenderer(); if(b) { @@ -1895,7 +1909,7 @@ void Scene_surface_mesh_item::showEdges(bool b) void Scene_surface_mesh_item::showFaces(bool b) { CGAL::Three::Viewer_interface* viewer = - qobject_cast(QGLViewer::QGLViewerPool().first()); + qobject_cast(CGAL::QGLViewer::QGLViewerPool().first()); TextRenderer *renderer = viewer->textRenderer(); if(b) { @@ -1916,7 +1930,7 @@ void Scene_surface_mesh_item::showFaces(bool b) void Scene_surface_mesh_item::showPrimitives(bool) { CGAL::Three::Viewer_interface* viewer = - qobject_cast(QGLViewer::QGLViewerPool().first()); + qobject_cast(CGAL::QGLViewer::QGLViewerPool().first()); printAllIds(viewer); } void Scene_surface_mesh_item::zoomToId() @@ -1930,7 +1944,7 @@ void Scene_surface_mesh_item::zoomToId() return; CGAL::Three::Viewer_interface* viewer = - qobject_cast(QGLViewer::QGLViewerPool().first()); + qobject_cast(CGAL::QGLViewer::QGLViewerPool().first()); Point_3 p; QString id = text.right(text.length()-1); int return_value = ::zoomToId(*d->smesh_, text, viewer, selected_fh, p); diff --git a/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.cpp b/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.cpp index 319f903df5c..044837d7348 100644 --- a/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_textured_polyhedron_item.cpp @@ -194,7 +194,7 @@ Scene_textured_polyhedron_item_priv::compute_normals_and_vertices(void) const typedef Base::Facet Facet; typedef Base::Facet_iterator Facet_iterator; - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); //Facets Facet_iterator f = poly->facets_begin(); diff --git a/Polyhedron/demo/Polyhedron/Scene_textured_surface_mesh_item.cpp b/Polyhedron/demo/Polyhedron/Scene_textured_surface_mesh_item.cpp index 4a51f6c1a88..70e4354c7d2 100644 --- a/Polyhedron/demo/Polyhedron/Scene_textured_surface_mesh_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_textured_surface_mesh_item.cpp @@ -148,7 +148,7 @@ Scene_textured_surface_mesh_item_priv::compute_normals_and_vertices(void) const typedef boost::graph_traits::face_iterator face_iterator; typedef boost::graph_traits::face_iterator face_iterator; - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); //Faces SMesh::Property_map positions = diff --git a/Polyhedron/demo/Polyhedron/TextRenderer.cpp b/Polyhedron/demo/Polyhedron/TextRenderer.cpp index 78ac4bfcdd7..2821f4bfc7a 100644 --- a/Polyhedron/demo/Polyhedron/TextRenderer.cpp +++ b/Polyhedron/demo/Polyhedron/TextRenderer.cpp @@ -8,7 +8,7 @@ void TextRenderer::draw(CGAL::Three::Viewer_interface *viewer) if (!painter->isActive()) painter->begin(viewer); QRect rect; - qglviewer::Camera* camera = viewer->camera(); + CGAL::qglviewer::Camera* camera = viewer->camera(); //Display the items textItems Q_FOREACH(TextListItem* list, textItems) { @@ -19,19 +19,19 @@ void TextRenderer::draw(CGAL::Three::Viewer_interface *viewer) ) Q_FOREACH(TextItem* item, list->textList()) { - qglviewer::Vec src(item->position().x(), item->position().y(),item->position().z()); + CGAL::qglviewer::Vec src(item->position().x(), item->position().y(),item->position().z()); if(viewer->testDisplayId(src.x, src.y, src.z)) { if(item->is_3D()) - rect = QRect(camera->projectedCoordinatesOf(src).x-item->width()/2, - camera->projectedCoordinatesOf(src).y-item->height()/2, - item->width(), - item->height()); + rect = QRect(int(camera->projectedCoordinatesOf(src).x-item->width()/2), + int(camera->projectedCoordinatesOf(src).y-item->height()/2), + int(item->width()), + int(item->height())); else - rect = QRect(src.x-item->width()/2, - src.y-item->height()/2, - item->width(), - item->height()); + rect = QRect(int(src.x-item->width()/2), + int(src.y-item->height()/2), + int(item->width()), + int(item->height())); painter->setFont(item->font()); painter->setPen(QPen(item->color())); @@ -43,23 +43,23 @@ void TextRenderer::draw(CGAL::Three::Viewer_interface *viewer) //Display the local TextItems Q_FOREACH(TextItem* item, local_textItems) { - qglviewer::Vec src(item->position().x(), item->position().y(),item->position().z()); + CGAL::qglviewer::Vec src(item->position().x(), item->position().y(),item->position().z()); if(item->is_3D()) { if(item->is_always_visible() || viewer->testDisplayId(src.x, src.y, src.z)) { - rect = QRect(camera->projectedCoordinatesOf(src).x-item->width()/2, - camera->projectedCoordinatesOf(src).y-item->height()/2, - item->width(), - item->height()); + rect = QRect(int(camera->projectedCoordinatesOf(src).x-item->width()/2), + int(camera->projectedCoordinatesOf(src).y-item->height()/2), + int(item->width()), + int(item->height())); } } else { - rect = QRect(src.x-item->width()/2, - src.y-item->height()/2, - item->width(), - item->height()); + rect = QRect(int(src.x-item->width()/2), + int(src.y-item->height()/2), + int(item->width()), + int(item->height())); } painter->setFont(item->font()); painter->setPen(QPen(item->color())); diff --git a/Polyhedron/demo/Polyhedron/Viewer.cpp b/Polyhedron/demo/Polyhedron/Viewer.cpp index f4a42bf5259..6513f174988 100644 --- a/Polyhedron/demo/Polyhedron/Viewer.cpp +++ b/Polyhedron/demo/Polyhedron/Viewer.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include @@ -13,6 +12,7 @@ #include #include #include +#include #if defined(_WIN32) #include @@ -30,49 +30,24 @@ public: bool inFastDrawing; bool inDrawWithNames; bool clipping; + bool projection_is_ortho; QVector4D clipbox[6]; QPainter *painter; - // F P S d i s p l a y - QTime fpsTime; - unsigned int fpsCounter; - QString fpsString; - float f_p_s; // M e s s a g e s QString message; bool _displayMessage; QTimer messageTimer; QOpenGLFunctions_4_3_Compatibility* _recentFunctions; - bool is_ogl_4_3; bool is_2d_selection_mode; - - //! Holds useful data to draw the axis system - struct AxisData - { - std::vector *vertices; - std::vector *normals; - std::vector *colors; - }; + QOpenGLDebugLogger *logger; //! The buffers used to draw the axis system - QOpenGLBuffer buffers[8]; + QOpenGLBuffer buffer; //! The VAO used to draw the axis system - QOpenGLVertexArrayObject vao[4]; - //! The rendering program used to draw the axis system - QOpenGLShaderProgram rendering_program; + QOpenGLVertexArrayObject vao; //! The rendering program used to draw the distance QOpenGLShaderProgram rendering_program_dist; QList distance_text; - //! Holds the vertices data for the axis system - std::vector v_Axis; - //! Holds the normals data for the axis system - std::vector n_Axis; - //! Holds the color data for the axis system - std::vector c_Axis; - //! Decides if the axis system must be drawn or not - bool axis_are_displayed; - bool grid_is_displayed; - std::size_t grid_size; - std::size_t v_gaxis_size; //! Decides if the text is displayed in the drawVisualHints function. bool has_text; //! Decides if the distance between APoint and BPoint must be drawn; @@ -83,33 +58,19 @@ public: QImage static_image; //!Draws the distance between two selected points. void showDistance(QPoint); - qglviewer::Vec APoint; - qglviewer::Vec BPoint; - qglviewer::Vec offset; + CGAL::qglviewer::Vec APoint; + CGAL::qglviewer::Vec BPoint; bool is_d_pressed; bool extension_is_found; + int quality; TextRenderer *textRenderer; - /*! - * \brief makeArrow creates an arrow and stores it in a struct of vectors. - * \param R the radius of the arrow. - * \param prec the precision of the quadric. The lower this value is, the higher precision you get. - * It can be any int between 1 and 360. - * \param from the starting point of the arrow. - * \param to the destination point of the arrow (the pointed extremity). - * \param color the RGB color of the arrow. - * \param data the struct of std::vector that will contain the results. - */ - void makeArrow(double R, int prec, qglviewer::Vec from, qglviewer::Vec to, qglviewer::Vec color, AxisData &data); - void drawGrid(qreal size, int nbSubdivisions=10); //!Clears the distance display void clearDistancedisplay(); void draw_aux(bool with_names, Viewer*); //! Contains all the programs for the item rendering. mutable std::vector shader_programs; QMatrix4x4 projectionMatrix; - void setFrustum(double l, double r, double t, double b, double n, double f); - QImage* takeSnapshot(Viewer* viewer, int quality, int background_color, QSize size, double oversampling, bool expand); void sendSnapshotToClipboard(Viewer*); }; Viewer::Viewer(QWidget* parent, bool antialiasing) @@ -117,6 +78,7 @@ Viewer::Viewer(QWidget* parent, bool antialiasing) { d = new Viewer_impl; d->scene = 0; + d->projection_is_ortho = false; d->initialized = false; d->antialiasing = antialiasing; d->twosides = false; @@ -126,21 +88,17 @@ Viewer::Viewer(QWidget* parent, bool antialiasing) d->inDrawWithNames = false; d->clipping = false; d->shader_programs.resize(NB_OF_PROGRAMS); - d->offset = qglviewer::Vec(0,0,0); d->textRenderer = new TextRenderer(); d->is_2d_selection_mode = false; connect( d->textRenderer, SIGNAL(sendMessage(QString,int)), this, SLOT(printMessage(QString,int)) ); connect(&d->messageTimer, SIGNAL(timeout()), SLOT(hideMessage())); - setShortcut(EXIT_VIEWER, 0); - setShortcut(DRAW_AXIS, 0); + setShortcut(CGAL::qglviewer::EXIT_VIEWER, 0); setKeyDescription(Qt::Key_T, tr("Turn the camera by 180 degrees")); setKeyDescription(Qt::Key_M, tr("Toggle macro mode: useful to view details very near from the camera, " "but decrease the z-buffer precision")); - setKeyDescription(Qt::Key_A, - tr("Toggle the axis system visibility.")); setKeyDescription(Qt::Key_I + Qt::CTRL, tr("Toggle the primitive IDs visibility of the selected Item.")); setKeyDescription(Qt::Key_D, @@ -148,14 +106,13 @@ Viewer::Viewer(QWidget* parent, bool antialiasing) setKeyDescription(Qt::Key_F5, tr("Reload selected items if possible.")); -#if QGLVIEWER_VERSION >= 0x020501 //modify mouse bindings that have been updated - setMouseBinding(Qt::Key(0), Qt::NoModifier, Qt::LeftButton, RAP_FROM_PIXEL, true, Qt::RightButton); + setMouseBinding(Qt::Key(0), Qt::NoModifier, Qt::LeftButton, CGAL::qglviewer::RAP_FROM_PIXEL, true, Qt::RightButton); setMouseBindingDescription(Qt::ShiftModifier, Qt::RightButton, tr("Select and pop context menu")); - setMouseBinding(Qt::Key_R, Qt::NoModifier, Qt::LeftButton, RAP_FROM_PIXEL); + setMouseBinding(Qt::Key_R, Qt::NoModifier, Qt::LeftButton, CGAL::qglviewer::RAP_FROM_PIXEL); //use the new API for these - setMouseBinding(Qt::ShiftModifier, Qt::LeftButton, SELECT); + setMouseBinding(Qt::ShiftModifier, Qt::LeftButton, CGAL::qglviewer::SELECT); setMouseBindingDescription(Qt::Key(0), Qt::ShiftModifier, Qt::LeftButton, tr("Selects and display context " @@ -168,27 +125,15 @@ Viewer::Viewer(QWidget* parent, bool antialiasing) setMouseBindingDescription(Qt::Key_O, Qt::NoModifier, Qt::LeftButton, tr("Move the camera orthogonally to the picked facet of a Scene_polyhedron_item or " "to the current selection of a Scene_points_with_normal_item.")); -#else - setMouseBinding(Qt::SHIFT + Qt::LeftButton, SELECT); - setMouseBindingDescription(Qt::SHIFT + Qt::RightButton, - tr("Selects and display context " - "menu of the selected item")); -#endif // QGLVIEWER_VERSION >= 2.5.0 prev_radius = sceneRadius(); - d->axis_are_displayed = true; - d->grid_is_displayed = false; - d->grid_size = 0; d->has_text = false; d->i_is_pressed = false; d->z_is_pressed = false; - d->fpsTime.start(); - d->fpsCounter=0; - d->f_p_s=0.0; - d->fpsString=tr("%1Hz", "Frames per seconds, in Hertz").arg("?"); d->distance_is_displayed = false; d->is_d_pressed = false; d->viewer = this; + setTextIsEnabled(true); } Viewer::~Viewer() @@ -244,62 +189,24 @@ void Viewer::fastDraw() d->draw_aux(false, this); } -void Viewer::initializeGL() +void Viewer::init() { -#if QGLVIEWER_VERSION >= 0x020700 - - QSurfaceFormat format; - format.setDepthBufferSize(24); - format.setStencilBufferSize(8); - format.setVersion(4,3); - format.setProfile(QSurfaceFormat::CompatibilityProfile); - format.setSamples(0); - context()->setFormat(format); - bool created = context()->create(); - if(!created || context()->format().profile() != QSurfaceFormat::CompatibilityProfile) { - // impossible to get a 4.3 compatibility profile, retry with 2.0 - format.setVersion(2,1); - context()->setFormat(format); - created = context()->create(); - d->is_ogl_4_3 = false; + if(!isOpenGL_4_3()) + { + std::cerr<<"The openGL context initialization failed " + "and the default context (2.1) will be used" <is_ogl_4_3 = true; d->_recentFunctions = new QOpenGLFunctions_4_3_Compatibility(); - } - CGAL_warning_msg(created && context()->isValid(), "The openGL context initialization failed " - "and the default context (2.0) will be used" ); - makeCurrent(); -#else - QGLFormat format; - format.setVersion(4,3); - format.setProfile(QGLFormat::CompatibilityProfile); - QGLContext *new_context = new QGLContext(format, this); - new_context->setFormat(format); - bool created = new_context->create(); - if(!created || new_context->format().profile() != QGLFormat::CompatibilityProfile) { - // impossible to get a 4.3 compatibility profile, retry with 2.0 - format.setVersion(2,1); - new_context->setFormat(format); - created = new_context->create(); - d->is_ogl_4_3 = false; - } - else - { - d->is_ogl_4_3 = true; - d->_recentFunctions = new QOpenGLFunctions_4_3_Compatibility(); - } - CGAL_warning_msg(created && new_context->isValid(), "The openGL context initialization failed " - "and the default context (2.0) will be used" ); - this->setContext(new_context); - context()->makeCurrent(); -#endif - QGLViewer::initializeGL(); - initializeOpenGLFunctions(); - if(isOpenGL_4_3()) - { - d->_recentFunctions->initializeOpenGLFunctions(); + d->logger = new QOpenGLDebugLogger(this); + if(!d->logger->initialize()) + qDebug()<<"logger could not init."; + else{ + connect(d->logger, SIGNAL(messageLogged(QOpenGLDebugMessage)), this, SLOT(messageLogged(QOpenGLDebugMessage))); + d->logger->startLogging(); + } + d->_recentFunctions->initializeOpenGLFunctions(); } glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDARBPROC)this->context()->getProcAddress("glDrawArraysInstancedARB"); if(!glDrawArraysInstanced) @@ -321,100 +228,13 @@ void Viewer::initializeGL() setBackgroundColor(::Qt::white); - d->vao[0].create(); - for(int i=0; i<3; i++) - d->buffers[i].create(); + d->vao.create(); + d->buffer.create(); - //Vertex source code - const char vertex_source[] = - { - "#version 120 \n" - "attribute highp vec4 vertex;\n" - "attribute highp vec3 normal;\n" - "attribute highp vec4 colors;\n" - "uniform highp mat4 mvp_matrix;\n" - "uniform highp mat4 mv_matrix; \n" - "varying highp vec4 fP; \n" - "varying highp vec3 fN; \n" - "varying highp vec4 color; \n" - "void main(void)\n" - "{\n" - " color = colors; \n" - " fP = mv_matrix * vertex; \n" - " fN = mat3(mv_matrix)* normal; \n" - " gl_Position = vec4(mvp_matrix * vertex); \n" - "} \n" - "\n" - }; - //Fragment source code - const char fragment_source[] = - { - "#version 120 \n" - "varying highp vec4 color; \n" - "varying highp vec4 fP; \n" - "varying highp vec3 fN; \n" - "uniform highp vec4 light_pos; \n" - "uniform highp vec4 light_diff; \n" - "uniform highp vec4 light_spec; \n" - "uniform highp vec4 light_amb; \n" - "uniform highp float spec_power ; \n" - - "void main(void) { \n" - - " vec3 L = light_pos.xyz - fP.xyz; \n" - " vec3 V = -fP.xyz; \n" - " vec3 N; \n" - " if(fN == vec3(0.0,0.0,0.0)) \n" - " N = vec3(0.0,0.0,0.0); \n" - " else \n" - " N = normalize(fN); \n" - " L = normalize(L); \n" - " V = normalize(V); \n" - " vec3 R = reflect(-L, N); \n" - " vec4 diffuse = max(abs(dot(N,L)),0.0) * light_diff*color; \n" - " vec4 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; \n" - - "gl_FragColor = color*light_amb + diffuse + specular; \n" - "} \n" - "\n" - }; - - QOpenGLShader *vertex_shader = new QOpenGLShader(QOpenGLShader::Vertex); - if(!vertex_shader->compileSourceCode(vertex_source)) - { - std::cerr<<"Compiling vertex source FAILED"<compileSourceCode(fragment_source)) - { - std::cerr<<"Compiling fragmentsource FAILED"<rendering_program.addShader(vertex_shader)) - { - std::cerr<<"adding vertex shader FAILED"<rendering_program.addShader(fragment_shader)) - { - std::cerr<<"adding fragment shader FAILED"<rendering_program.bindAttributeLocation("colors", 1); - if(!d->rendering_program.link()) - { - //std::cerr<<"linking Program FAILED"<rendering_program.log(); - } + QOpenGLShader *vertex_shader, *fragment_shader; + //setting the program used for the distance { - d->vao[1].create(); - d->buffers[3].create(); - d->vao[2].create(); - d->vao[3].create(); - d->buffers[4].create(); - d->buffers[5].create(); - d->buffers[6].create(); - d->buffers[7].create(); //Vertex source code const char vertex_source_dist[] = { @@ -461,42 +281,6 @@ void Viewer::initializeGL() qDebug() << d->rendering_program_dist.log(); } } - - Viewer_impl::AxisData data; - d->v_Axis.resize(0); - d->n_Axis.resize(0); - d->c_Axis.resize(0); - data.vertices = &d->v_Axis; - data.normals = &d->n_Axis; - data.colors = &d->c_Axis; - GLdouble l = 1.0; - d->makeArrow(0.06,10, qglviewer::Vec(0,0,0),qglviewer::Vec(l,0,0),qglviewer::Vec(1,0,0), data); - d->makeArrow(0.06,10, qglviewer::Vec(0,0,0),qglviewer::Vec(0,l,0),qglviewer::Vec(0,1,0), data); - d->makeArrow(0.06,10, qglviewer::Vec(0,0,0),qglviewer::Vec(0,0,l),qglviewer::Vec(0,0,1), data); - - d->rendering_program.bind(); - d->vao[0].bind(); - d->buffers[0].bind(); - d->buffers[0].allocate(d->v_Axis.data(), static_cast(d->v_Axis.size()) * sizeof(float)); - d->rendering_program.enableAttributeArray("vertex"); - d->rendering_program.setAttributeBuffer("vertex",GL_FLOAT,0,3); - d->buffers[0].release(); - - d->buffers[1].bind(); - d->buffers[1].allocate(d->n_Axis.data(), static_cast(d->n_Axis.size() * sizeof(float))); - d->rendering_program.enableAttributeArray("normal"); - d->rendering_program.setAttributeBuffer("normal",GL_FLOAT,0,3); - d->buffers[1].release(); - - d->buffers[2].bind(); - d->buffers[2].allocate(d->c_Axis.data(), static_cast(d->c_Axis.size() * sizeof(float))); - d->rendering_program.enableAttributeArray("colors"); - d->rendering_program.setAttributeBuffer("colors",GL_FLOAT,0,3); - d->buffers[2].release(); - d->vao[0].release(); - - d->rendering_program.release(); - d->painter = new QPainter(); d->initialized = true; } @@ -534,13 +318,13 @@ void Viewer::mousePressEvent(QMouseEvent* event) } else { makeCurrent(); - QGLViewer::mousePressEvent(event); + CGAL::QGLViewer::mousePressEvent(event); } } void Viewer::mouseDoubleClickEvent(QMouseEvent* event) { makeCurrent(); - QGLViewer::mouseDoubleClickEvent(event); + CGAL::QGLViewer::mouseDoubleClickEvent(event); } #include @@ -551,7 +335,7 @@ void Viewer::contextMenuEvent(QContextMenuEvent* event) event->accept(); } else { - QGLViewer::contextMenuEvent(event); + CGAL::QGLViewer::contextMenuEvent(event); } } @@ -577,14 +361,6 @@ void Viewer::keyPressEvent(QKeyEvent* e) return; } - else if(e->key() == Qt::Key_A) { - d->axis_are_displayed = !d->axis_are_displayed; - update(); - } - else if(e->key() == Qt::Key_G) { - d->grid_is_displayed = !d->grid_is_displayed; - update(); - } else if(e->key() == Qt::Key_I) { d->i_is_pressed = true; } @@ -623,13 +399,13 @@ void Viewer::keyPressEvent(QKeyEvent* e) } else if(e->key() == Qt::Key_S && e->modifiers() & Qt::ControlModifier){ - this->saveSnapshot(true,true); + this->saveSnapshot(); return; } //forward the event to the scene (item handling of the event) if (! d->scene->keyPressEvent(e) ) - QGLViewer::keyPressEvent(e); + CGAL::QGLViewer::keyPressEvent(e); } void Viewer::keyReleaseEvent(QKeyEvent *e) @@ -648,12 +424,12 @@ void Viewer::keyReleaseEvent(QKeyEvent *e) } d->is_d_pressed = false; } - QGLViewer::keyReleaseEvent(e); + CGAL::QGLViewer::keyReleaseEvent(e); } void Viewer::turnCameraBy180Degres() { - qglviewer::Camera* camera = this->camera(); - using qglviewer::ManipulatedCameraFrame; + CGAL::qglviewer::Camera* camera = this->camera(); + using CGAL::qglviewer::ManipulatedCameraFrame; ManipulatedCameraFrame frame_from(*camera->frame()); camera->setViewDirection(-camera->viewDirection()); @@ -709,7 +485,7 @@ bool Viewer::inDrawWithNames() const { void Viewer::drawWithNames() { - QGLViewer::draw(); + CGAL::QGLViewer::draw(); d->draw_aux(true, this); } @@ -717,18 +493,27 @@ void Viewer::postSelection(const QPoint& pixel) { Q_EMIT selected(this->selectedName()); bool found = false; - qglviewer::Vec point = camera()->pointUnderPixel(pixel, found) - d->offset; + CGAL::qglviewer::Vec point = camera()->pointUnderPixel(pixel, found) - offset(); if(found) { Q_EMIT selectedPoint(point.x, point.y, point.z); - const qglviewer::Vec orig = camera()->position() - d->offset; - const qglviewer::Vec dir = point - orig; + CGAL::qglviewer::Vec dir; + CGAL::qglviewer::Vec orig; + if(d->projection_is_ortho) + { + dir = camera()->viewDirection(); + orig = point; + } + else{ + orig = camera()->position() - offset(); + dir = point - orig; + } Q_EMIT selectionRay(orig.x, orig.y, orig.z, dir.x, dir.y, dir.z); } } -bool CGAL::Three::Viewer_interface::readFrame(QString s, qglviewer::Frame& frame) +bool CGAL::Three::Viewer_interface::readFrame(QString s, CGAL::qglviewer::Frame& frame) { QStringList list = s.split(" ", QString::SkipEmptyParts); if(list.size() != 7) @@ -747,7 +532,7 @@ bool CGAL::Three::Viewer_interface::readFrame(QString s, qglviewer::Frame& frame orient[i] = list[i + 3].toDouble(&ok); if(!ok) return false; } - frame.setPosition(qglviewer::Vec(vec[0], + frame.setPosition(CGAL::qglviewer::Vec(vec[0], vec[1], vec[2])); frame.setOrientation(orient[0], @@ -757,9 +542,9 @@ bool CGAL::Three::Viewer_interface::readFrame(QString s, qglviewer::Frame& frame return true; } -QString CGAL::Three::Viewer_interface::dumpFrame(const qglviewer::Frame& frame) { - const qglviewer::Vec pos = frame.position(); - const qglviewer::Quaternion q = frame.orientation(); +QString CGAL::Three::Viewer_interface::dumpFrame(const CGAL::qglviewer::Frame& frame) { + const CGAL::qglviewer::Vec pos = frame.position(); + const CGAL::qglviewer::Quaternion q = frame.orientation(); return QString("%1 %2 %3 %4 %5 %6 %7") .arg(pos[0]) @@ -772,7 +557,7 @@ QString CGAL::Three::Viewer_interface::dumpFrame(const qglviewer::Frame& frame) } bool Viewer::moveCameraToCoordinates(QString s, float animation_duration) { - qglviewer::Frame new_frame; + CGAL::qglviewer::Frame new_frame; if(readFrame(s, new_frame)) { camera()->interpolateTo(new_frame, animation_duration); return true; @@ -806,7 +591,10 @@ void Viewer::attribBuffers(int program_name) const { this->camera()->getModelViewMatrix(d_mat); for (int i=0; i<16; ++i) mv_mat.data()[i] = GLfloat(d_mat[i]); - mvp_mat = d->projectionMatrix*mv_mat; + this->camera()->getModelViewProjectionMatrix(d_mat); + for (int i=0; i<16; ++i) + mvp_mat.data()[i] = GLfloat(d_mat[i]); + const_cast(this)->glGetIntegerv(GL_LIGHT_MODEL_TWO_SIDE, &is_both_sides); @@ -884,262 +672,20 @@ void Viewer::attribBuffers(int program_name) const { void Viewer::beginSelection(const QPoint &point) { - makeCurrent(); - glEnable(GL_SCISSOR_TEST); - glScissor(point.x(), camera()->screenHeight()-1-point.y(), 1, 1); - d->scene->setPickedPixel(point); + CGAL::QGLViewer::beginSelection(point); + d->scene->setPickedPixel(point); } -void Viewer::endSelection(const QPoint&) +void Viewer::endSelection(const QPoint& point) { - glDisable(GL_SCISSOR_TEST); + CGAL::QGLViewer::endSelection(point); //redraw the true scene for the glReadPixel in postSelection(); d->draw_aux(false, this); } -void Viewer_impl::makeArrow(double R, int prec, qglviewer::Vec from, qglviewer::Vec to, qglviewer::Vec color, Viewer_impl::AxisData &data) -{ - qglviewer::Vec temp = to-from; - QVector3D dir = QVector3D(temp.x, temp.y, temp.z); - QMatrix4x4 mat; - mat.setToIdentity(); - mat.translate(from.x, from.y, from.z); - mat.scale(dir.length()); - dir.normalize(); - float angle = 0.0; - if(std::sqrt((dir.x()*dir.x()+dir.y()*dir.y())) > 1) - angle = 90.0f; - else - angle =acos(dir.y()/std::sqrt(dir.x()*dir.x()+dir.y()*dir.y()+dir.z()*dir.z()))*180.0/M_PI; - - QVector3D axis; - axis = QVector3D(dir.z(), 0, -dir.x()); - mat.rotate(angle, axis); - - //Head - const float Rf = static_cast(R); - for(int d = 0; d<360; d+= 360/prec) - { - float D = (float) (d * M_PI / 180.); - float a = (float) std::atan(Rf / 0.33); - QVector4D p(0., 1., 0, 1.); - QVector4D n(Rf*2.*sin(D), sin(a), Rf*2.*cos(D), 1.); - QVector4D pR = mat*p; - QVector4D nR = mat*n; - - //point A1 - data.vertices->push_back(pR.x()); - data.vertices->push_back(pR.y()); - data.vertices->push_back(pR.z()); - data.normals->push_back(nR.x()); - data.normals->push_back(nR.y()); - data.normals->push_back(nR.z()); - data.colors->push_back((float)color.x); - data.colors->push_back((float)color.y); - data.colors->push_back((float)color.z); - - //point B1 - p = QVector4D(Rf*2.*sin(D), 0.66f, Rf*2.* cos(D), 1.f); - n = QVector4D(sin(D), sin(a), cos(D), 1.); - pR = mat*p; - nR = mat*n; - data.vertices->push_back(pR.x()); - data.vertices->push_back(pR.y()); - data.vertices->push_back(pR.z()); - data.normals->push_back(nR.x()); - data.normals->push_back(nR.y()); - data.normals->push_back(nR.z()); - data.colors->push_back((float)color.x); - data.colors->push_back((float)color.y); - data.colors->push_back((float)color.z); - //point C1 - D = (d+360/prec)*M_PI/180.0; - p = QVector4D(Rf*2.* sin(D), 0.66f, Rf *2.* cos(D), 1.f); - n = QVector4D(sin(D), sin(a), cos(D), 1.0); - pR = mat*p; - nR = mat*n; - - data.vertices->push_back(pR.x()); - data.vertices->push_back(pR.y()); - data.vertices->push_back(pR.z()); - data.normals->push_back(nR.x()); - data.normals->push_back(nR.y()); - data.normals->push_back(nR.z()); - data.colors->push_back((float)color.x); - data.colors->push_back((float)color.y); - data.colors->push_back((float)color.z); - - } - - //cylinder - //body of the cylinder - for(int d = 0; d<360; d+= 360/prec) - { - //point A1 - double D = d*M_PI/180.0; - QVector4D p(Rf*sin(D), 0.66f, Rf*cos(D), 1.f); - QVector4D n(sin(D), 0.f, cos(D), 1.f); - QVector4D pR = mat*p; - QVector4D nR = mat*n; - - data.vertices->push_back(pR.x()); - data.vertices->push_back(pR.y()); - data.vertices->push_back(pR.z()); - data.normals->push_back(nR.x()); - data.normals->push_back(nR.y()); - data.normals->push_back(nR.z()); - data.colors->push_back(color.x); - data.colors->push_back(color.y); - data.colors->push_back(color.z); - //point B1 - p = QVector4D(Rf * sin(D),0,Rf*cos(D), 1.0); - n = QVector4D(sin(D), 0, cos(D), 1.0); - pR = mat*p; - nR = mat*n; - - - data.vertices->push_back(pR.x()); - data.vertices->push_back(pR.y()); - data.vertices->push_back(pR.z()); - data.normals->push_back(nR.x()); - data.normals->push_back(nR.y()); - data.normals->push_back(nR.z()); - data.colors->push_back(color.x); - data.colors->push_back(color.y); - data.colors->push_back(color.z); - //point C1 - D = (d+360/prec)*M_PI/180.0; - p = QVector4D(Rf * sin(D),0,Rf*cos(D), 1.0); - n = QVector4D(sin(D), 0, cos(D), 1.0); - pR = mat*p; - nR = mat*n; - data.vertices->push_back(pR.x()); - data.vertices->push_back(pR.y()); - data.vertices->push_back(pR.z()); - data.normals->push_back(nR.x()); - data.normals->push_back(nR.y()); - data.normals->push_back(nR.z()); - data.colors->push_back(color.x); - data.colors->push_back(color.y); - data.colors->push_back(color.z); - //point A2 - D = (d+360/prec)*M_PI/180.0; - - p = QVector4D(Rf * sin(D),0,Rf*cos(D), 1.0); - n = QVector4D(sin(D), 0, cos(D), 1.0); - pR = mat*p; - nR = mat*n; - data.vertices->push_back(pR.x()); - data.vertices->push_back(pR.y()); - data.vertices->push_back(pR.z()); - data.normals->push_back(nR.x()); - data.normals->push_back(nR.y()); - data.normals->push_back(nR.z()); - data.colors->push_back((float)color.x); - data.colors->push_back((float)color.y); - data.colors->push_back((float)color.z); - //point B2 - p = QVector4D(Rf * sin(D), 0.66f, Rf*cos(D), 1.f); - n = QVector4D(sin(D), 0, cos(D), 1.0); - pR = mat*p; - nR = mat*n; - data.vertices->push_back(pR.x()); - data.vertices->push_back(pR.y()); - data.vertices->push_back(pR.z()); - data.normals->push_back(nR.x()); - data.normals->push_back(nR.y()); - data.normals->push_back(nR.z()); - data.colors->push_back((float)color.x); - data.colors->push_back((float)color.y); - data.colors->push_back((float)color.z); - //point C2 - D = d*M_PI/180.0; - p = QVector4D(Rf * sin(D), 0.66f, Rf*cos(D), 1.f); - n = QVector4D(sin(D), 0.f, cos(D), 1.f); - pR = mat*p; - nR = mat*n; - data.vertices->push_back(pR.x()); - data.vertices->push_back(pR.y()); - data.vertices->push_back(pR.z()); - data.normals->push_back(nR.x()); - data.normals->push_back(nR.y()); - data.normals->push_back(nR.z()); - data.colors->push_back(color.x); - data.colors->push_back(color.y); - data.colors->push_back(color.z); - - } -} - void Viewer::drawVisualHints() { - QGLViewer::drawVisualHints(); - if(d->axis_are_displayed) - { - d->rendering_program.bind(); - qglviewer::Camera::Type camera_type = camera()->type(); - camera()->setType(qglviewer::Camera::ORTHOGRAPHIC); - QMatrix4x4 mvpMatrix; - QMatrix4x4 mvMatrix; - for(int i=0; i < 16; i++) - { - mvMatrix.data()[i] = camera()->orientation().inverse().matrix()[i]; - } - mvpMatrix.ortho(-1,1,-1,1,-1,1); - mvpMatrix = mvpMatrix*mvMatrix; - camera()->setType(camera_type); - QVector4D position(0.0f,0.0f,1.0f,1.0f ); - // define material - QVector4D ambient; - QVector4D diffuse; - QVector4D specular; - GLfloat shininess ; - // Ambient - ambient[0] = 0.29225f; - ambient[1] = 0.29225f; - ambient[2] = 0.29225f; - ambient[3] = 1.0f; - // Diffuse - diffuse[0] = 0.50754f; - diffuse[1] = 0.50754f; - diffuse[2] = 0.50754f; - diffuse[3] = 1.0f; - // Specular - specular[0] = 0.0f; - specular[1] = 0.0f; - specular[2] = 0.0f; - specular[3] = 0.0f; - // Shininess - shininess = 51.2f; - - d->rendering_program.setUniformValue("light_pos", position); - d->rendering_program.setUniformValue("mvp_matrix", mvpMatrix); - d->rendering_program.setUniformValue("mv_matrix", mvMatrix); - d->rendering_program.setUniformValue("light_diff", diffuse); - d->rendering_program.setUniformValue("light_spec", specular); - d->rendering_program.setUniformValue("light_amb", ambient); - d->rendering_program.setUniformValue("spec_power", shininess); - - d->vao[0].bind(); - int viewport[4]; - int scissor[4]; - - // The viewport and the scissor are changed to fit the upper right - // corner. Original values are saved. - glGetIntegerv(GL_VIEWPORT, viewport); - glGetIntegerv(GL_SCISSOR_BOX, scissor); - - // Axis viewport size, in pixels - const int size = 100; - glViewport(width()*devicePixelRatio()-size, height()*devicePixelRatio()-size, size, size); - glScissor (width()*devicePixelRatio()-size, height()*devicePixelRatio()-size, size, size); - glDrawArrays(GL_TRIANGLES, 0, static_cast(d->v_Axis.size() / 3)); - // The viewport and the scissor are restored. - glScissor(scissor[0],scissor[1],scissor[2],scissor[3]); - glViewport(viewport[0],viewport[1],viewport[2],viewport[3]); - d->vao[0].release(); - d->rendering_program.release(); - } + CGAL::QGLViewer::drawVisualHints(); if(d->distance_is_displayed) { @@ -1159,111 +705,39 @@ void Viewer::drawVisualHints() } d->rendering_program_dist.bind(); d->rendering_program_dist.setUniformValue("mvp_matrix", mvpMatrix); - d->vao[1].bind(); + d->vao.bind(); glDrawArrays(GL_POINTS, 0, static_cast(2)); glDrawArrays(GL_LINES, 0, static_cast(2)); - d->vao[1].release(); + d->vao.release(); d->rendering_program_dist.release(); glEnable(GL_DEPTH_TEST); glPointSize(1.0f); glLineWidth(1.0f); } - if(d->grid_is_displayed) - { - //draws the distance - QMatrix4x4 mvpMatrix; - double mat[16]; - camera()->getModelViewProjectionMatrix(mat); - //nullifies the translation - for(int i=0; i < 16; i++) - { - mvpMatrix.data()[i] = (float)mat[i]; - } - d->rendering_program_dist.bind(); - d->rendering_program_dist.setUniformValue("mvp_matrix", mvpMatrix); - d->vao[2].bind(); - glDrawArrays(GL_LINES, 0, static_cast(d->grid_size)); - d->vao[2].release(); - d->rendering_program_dist.release(); - - d->rendering_program.bind(); - QMatrix4x4 mvMatrix; - for(int i=0; i < 16; i++) - { - mvMatrix.data()[i] = camera()->orientation().inverse().matrix()[i]; - } - QVector4D position(0.0f,0.0f,1.0f,1.0f ); - // define material - QVector4D ambient; - QVector4D diffuse; - QVector4D specular; - GLfloat shininess ; - // Ambient - ambient[0] = 0.29225f; - ambient[1] = 0.29225f; - ambient[2] = 0.29225f; - ambient[3] = 1.0f; - // Diffuse - diffuse[0] = 0.50754f; - diffuse[1] = 0.50754f; - diffuse[2] = 0.50754f; - diffuse[3] = 1.0f; - // Specular - specular[0] = 0.0f; - specular[1] = 0.0f; - specular[2] = 0.0f; - specular[3] = 0.0f; - // Shininess - shininess = 51.2f; - - d->rendering_program.setUniformValue("light_pos", position); - d->rendering_program.setUniformValue("mvp_matrix", mvpMatrix); - d->rendering_program.setUniformValue("mv_matrix", mvMatrix); - d->rendering_program.setUniformValue("light_diff", diffuse); - d->rendering_program.setUniformValue("light_spec", specular); - d->rendering_program.setUniformValue("light_amb", ambient); - d->rendering_program.setUniformValue("spec_power", shininess); - - d->vao[3].bind(); - // Axis viewport size, in pixels - glDrawArrays(GL_TRIANGLES, 0, static_cast(d->v_gaxis_size / 3)); - // The viewport and the scissor are restored. - d->vao[3].release(); - d->rendering_program.release(); - } - if (!d->painter->isActive()) d->painter->begin(this); //So that the text is drawn in front of everything d->painter->beginNativePainting(); glDisable(GL_DEPTH_TEST); d->painter->endNativePainting(); - //prints FPS - TextItem *fps_text = new TextItem(20, int(1.5*((QApplication::font().pixelSize()>0)?QApplication::font().pixelSize():QApplication::font().pointSize())),0,d->fpsString,false, QFont(), Qt::gray); - if(FPSIsDisplayed()) - { - d->textRenderer->addText(fps_text); - } //Prints the displayMessage QFont font = QFont(); QFontMetrics fm(font); - TextItem *message_text = new TextItem(10 + fm.width(d->message)/2, height()-20, 0, d->message, false, QFont(), Qt::gray ); + TextItem *message_text = new TextItem(float(10 + fm.width(d->message)/2), + float(height()-20), + 0, d->message, false, + QFont(), Qt::gray ); if (d->_displayMessage) { d->textRenderer->addText(message_text); } d->textRenderer->draw(this); - if(FPSIsDisplayed()) - d->textRenderer->removeText(fps_text); + if (d->_displayMessage) d->textRenderer->removeText(message_text); } -void Viewer::resizeGL(int w, int h) -{ - QGLViewer::resizeGL(w,h); -} QOpenGLShaderProgram* Viewer::declare_program(int name, const char* v_shader, const char* f_shader) const @@ -1366,7 +840,7 @@ void Viewer::wheelEvent(QWheelEvent* e) update(); } else - QGLViewer::wheelEvent(e); + CGAL::QGLViewer::wheelEvent(e); } bool Viewer::testDisplayId(double x, double y, double z) @@ -1395,16 +869,17 @@ void Viewer::paintGL() else { d->painter->beginNativePainting(); - glClearColor(backgroundColor().redF(), backgroundColor().greenF(), backgroundColor().blueF(), 1.0); + glClearColor(GLfloat(backgroundColor().redF()), + GLfloat(backgroundColor().greenF()), + GLfloat(backgroundColor().blueF()), + 1.f); glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //set the default frustum - GLdouble d_mat[16]; - this->camera()->getProjectionMatrix(d_mat); - //Convert the GLdoubles matrices in GLfloats - for (int i=0; i<16; ++i) - d->projectionMatrix.data()[i] = GLfloat(d_mat[i]); - + if(d->projection_is_ortho) + camera()->setType(CGAL::qglviewer::Camera::ORTHOGRAPHIC); + else + camera()->setType(CGAL::qglviewer::Camera::PERSPECTIVE); preDraw(); draw(); postDraw(); @@ -1414,29 +889,6 @@ void Viewer::paintGL() doneCurrent(); } -void Viewer::postDraw() -{ - -#ifdef GL_RESCALE_NORMAL // OpenGL 1.2 Only... - glEnable(GL_RESCALE_NORMAL); -#endif - - if (cameraIsEdited()) - camera()->drawAllPaths(); - - // Pivot point, line when camera rolls, zoom region - drawVisualHints(); - - // FPS computation - const unsigned int maxCounter = 20; - if (++d->fpsCounter == maxCounter) - { - d->f_p_s = 1000.0 * maxCounter / d->fpsTime.restart(); - d->fpsString = tr("%1Hz", "Frames per seconds, in Hertz").arg(d->f_p_s, 0, 'f', ((d->f_p_s < 10.0)?1:0)); - d->fpsCounter = 0; - } - -} void Viewer::displayMessage(const QString &_message, int delay) { d->message = _message; @@ -1461,7 +913,7 @@ void Viewer_impl::showDistance(QPoint pixel) { static bool isAset = false; bool found; - qglviewer::Vec point; + CGAL::qglviewer::Vec point; point = viewer->camera()->pointUnderPixel(pixel, found); if(!isAset && found) { @@ -1479,38 +931,47 @@ void Viewer_impl::showDistance(QPoint pixel) // fills the buffers std::vector v; v.resize(6); - v[0] = APoint.x; v[1] = APoint.y; v[2] = APoint.z; - v[3] = BPoint.x; v[4] = BPoint.y; v[5] = BPoint.z; + v[0] = float(APoint.x); v[1] = float(APoint.y); v[2] = float(APoint.z); + v[3] = float(BPoint.x); v[4] = float(BPoint.y); v[5] = float(BPoint.z); rendering_program_dist.bind(); - vao[1].bind(); - buffers[3].bind(); - buffers[3].allocate(v.data(),6*sizeof(float)); + vao.bind(); + buffer.bind(); + buffer.allocate(v.data(),6*sizeof(float)); rendering_program_dist.enableAttributeArray("vertex"); rendering_program_dist.setAttributeBuffer("vertex",GL_FLOAT,0,3); - buffers[3].release(); - vao[1].release(); + buffer.release(); + vao.release(); rendering_program_dist.release(); distance_is_displayed = true; double dist = std::sqrt((BPoint.x-APoint.x)*(BPoint.x-APoint.x) + (BPoint.y-APoint.y)*(BPoint.y-APoint.y) + (BPoint.z-APoint.z)*(BPoint.z-APoint.z)); QFont font; font.setBold(true); - TextItem *ACoord = new TextItem(APoint.x, APoint.y, APoint.z,QString("A(%1,%2,%3)").arg(APoint.x-offset.x).arg(APoint.y-offset.y).arg(APoint.z-offset.z), true, font, Qt::red, true); + TextItem *ACoord = new TextItem(float(APoint.x), + float(APoint.y), + float(APoint.z), + QString("A(%1,%2,%3)").arg(APoint.x-viewer->offset().x).arg(APoint.y-viewer->offset().y).arg(APoint.z-viewer->offset().z), true, font, Qt::red, true); distance_text.append(ACoord); - TextItem *BCoord = new TextItem(BPoint.x, BPoint.y, BPoint.z,QString("B(%1,%2,%3)").arg(BPoint.x-offset.x).arg(BPoint.y-offset.y).arg(BPoint.z-offset.z), true, font, Qt::red, true); + TextItem *BCoord = new TextItem(float(BPoint.x), + float(BPoint.y), + float(BPoint.z), + QString("B(%1,%2,%3)").arg(BPoint.x-viewer->offset().x).arg(BPoint.y-viewer->offset().y).arg(BPoint.z-viewer->offset().z), true, font, Qt::red, true); distance_text.append(BCoord); - qglviewer::Vec centerPoint = 0.5*(BPoint+APoint); - TextItem *centerCoord = new TextItem(centerPoint.x, centerPoint.y, centerPoint.z,QString(" distance: %1").arg(dist), true, font, Qt::red, true); + CGAL::qglviewer::Vec centerPoint = 0.5*(BPoint+APoint); + TextItem *centerCoord = new TextItem(float(centerPoint.x), + float(centerPoint.y), + float(centerPoint.z), + QString(" distance: %1").arg(dist), true, font, Qt::red, true); distance_text.append(centerCoord); Q_FOREACH(TextItem* ti, distance_text) textRenderer->addText(ti); Q_EMIT(viewer->sendMessage(QString("First point : A(%1,%2,%3), second point : B(%4,%5,%6), distance between them : %7") - .arg(APoint.x-offset.x) - .arg(APoint.y-offset.y) - .arg(APoint.z-offset.z) - .arg(BPoint.x-offset.x) - .arg(BPoint.y-offset.y) - .arg(BPoint.z-offset.z) + .arg(APoint.x-viewer->offset().x) + .arg(APoint.y-viewer->offset().y) + .arg(APoint.z-viewer->offset().z) + .arg(BPoint.x-viewer->offset().x) + .arg(BPoint.y-viewer->offset().y) + .arg(BPoint.z-viewer->offset().z) .arg(dist))); } @@ -1527,204 +988,9 @@ void Viewer_impl::clearDistancedisplay() distance_text.clear(); } -void Viewer_impl::setFrustum(double l, double r, double t, double b, double n, double f) -{ - double A = 2*n/(r-l); - double B = (r+l)/(r-l); - double C = 2*n/(t-b); - double D = (t+b)/(t-b); - float E = -(f+n)/(f-n); - float F = -2*(f*n)/(f-n); - projectionMatrix.setRow(0, QVector4D(A,0,B,0)); - projectionMatrix.setRow(1, QVector4D(0,C,D,0)); - projectionMatrix.setRow(2, QVector4D(0,0,E,F)); - projectionMatrix.setRow(3, QVector4D(0,0,-1,0)); - -} - -#include "ui_ImageInterface.h" -class ImageInterface: public QDialog, public Ui::ImageInterface -{ - Q_OBJECT - qreal ratio; - QWidget *currentlyFocused; -public: - ImageInterface(QWidget *parent, qreal ratio) - : QDialog(parent), ratio(ratio) - { - currentlyFocused = NULL; - setupUi(this); - connect(imgHeight, SIGNAL(valueChanged(int)), - this, SLOT(imgHeightValueChanged(int))); - - connect(imgWidth, SIGNAL(valueChanged(int)), - this, SLOT(imgWidthValueChanged(int))); - - connect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), - this, SLOT(onFocusChanged(QWidget*, QWidget*))); - } -private Q_SLOTS: - void imgHeightValueChanged(int i) - { - if(currentlyFocused == imgHeight - && ratioCheckBox->isChecked()) - {imgWidth->setValue(i*ratio);} - } - - void imgWidthValueChanged(int i) - { - if(currentlyFocused == imgWidth - && ratioCheckBox->isChecked()) - {imgHeight->setValue(i/ratio);} - } - - void onFocusChanged(QWidget*, QWidget* now) - { - currentlyFocused = now; - } -}; - -void Viewer::saveSnapshot(bool, bool) -{ - qreal aspectRatio = width() / static_cast(height()); - static ImageInterface* imageInterface = NULL; - - if (!imageInterface) - imageInterface = new ImageInterface(this, aspectRatio); - - imageInterface->imgWidth->setValue(width()); - imageInterface->imgHeight->setValue(height()); - imageInterface->imgQuality->setValue(snapshotQuality()); - - if (imageInterface->exec() == QDialog::Rejected) - return; - QSize finalSize(imageInterface->imgWidth->value(), imageInterface->imgHeight->value()); - bool expand = imageInterface->expandFrustum->isChecked(); - QString fileName = QFileDialog::getSaveFileName(this, - tr("Save Snapshot"), "", tr("Image Files (*.png *.jpg *.bmp)")); - if(fileName.isEmpty()) - { - return; - } - QImage* image= d->takeSnapshot(this, imageInterface->imgQuality->value(), imageInterface->color_comboBox->currentIndex(), - finalSize, imageInterface->oversampling->value(), expand); - if(image) - { - image->save(fileName); - delete image; - } - -} -//copy a snapshot with transparent background with arbitrary quality values. -QImage* Viewer_impl::takeSnapshot(Viewer *viewer, int quality, int background_color, QSize finalSize, double oversampling, bool expand) -{ - viewer->makeCurrent(); - qreal aspectRatio = viewer->width() / static_cast(viewer->height()); - viewer->setSnapshotQuality(quality); - GLfloat alpha = 1.0f; - QColor previousBGColor = viewer->backgroundColor(); - switch(background_color) - { - case 0: - break; - case 1: - viewer->setBackgroundColor(QColor(Qt::transparent)); - alpha = 0.0f; - break; - case 2: - QColor c = QColorDialog::getColor(); - if(c.isValid()) { - viewer->setBackgroundColor(c); - } - else - return NULL; - break; - } - - - QSize subSize(int(viewer->width()/oversampling), int(viewer->height()/oversampling)); - QSize size=QSize(viewer->width(), viewer->height()); - - - qreal newAspectRatio = finalSize.width() / static_cast(finalSize.height()); - - qreal zNear = viewer->camera()->zNear(); - qreal zFar = viewer->camera()->zFar(); - - qreal xMin, yMin; - - if ((expand && (newAspectRatio>aspectRatio)) || (!expand && (newAspectRatiocamera()->fieldOfView() / 2.0); - xMin = newAspectRatio * yMin; - } - else - { - xMin = zNear * tan(viewer->camera()->fieldOfView() / 2.0) * aspectRatio; - yMin = xMin / newAspectRatio; - } - - QImage *image = new QImage(finalSize.width(), finalSize.height(), QImage::Format_ARGB32); - - if (image->isNull()) - { - QMessageBox::warning(viewer, "Image saving error", - "Unable to create resulting image", - QMessageBox::Ok, QMessageBox::NoButton); - viewer->setBackgroundColor(previousBGColor); - return NULL; - } - - qreal scaleX = subSize.width() / static_cast(finalSize.width()); - qreal scaleY = subSize.height() / static_cast(finalSize.height()); - - qreal deltaX = 2.0 * xMin * scaleX; - qreal deltaY = 2.0 * yMin * scaleY; - - int nbX = finalSize.width() / subSize.width(); - int nbY = finalSize.height() / subSize.height(); - - // Extra subimage on the right/bottom border(s) if needed - if (nbX * subSize.width() < finalSize.width()) - nbX++; - if (nbY * subSize.height() < finalSize.height()) - nbY++; - - QOpenGLFramebufferObject fbo(size, QOpenGLFramebufferObject::CombinedDepthStencil); - for (int i=0; iglClearColor(viewer->backgroundColor().redF(), viewer->backgroundColor().greenF(), viewer->backgroundColor().blueF(), alpha); - viewer->preDraw(); - viewer->draw(); - fbo.release(); - - QImage snapshot = fbo.toImage(); - QImage subImage = snapshot.scaled(subSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - // Copy subImage in image - for (int ii=0; iiwidth()) - break; - for (int jj=0; jjheight()) - break; - image->setPixel(fi, fj, subImage.pixel(ii,jj)); - } - } - } - if(background_color !=0) - viewer->setBackgroundColor(previousBGColor); - return image; -} void Viewer_impl::sendSnapshotToClipboard(Viewer *viewer) { - QImage * snap = takeSnapshot(viewer, 95, 1, 2*viewer->size(), 1, true); + QImage * snap = viewer->takeSnapshot(CGAL::qglviewer::TRANSPARENT_BACKGROUND, 2*viewer->size(), 1, true); if(snap) { #if defined(_WIN32) @@ -1747,21 +1013,10 @@ void Viewer_impl::sendSnapshotToClipboard(Viewer *viewer) } void Viewer::SetOrthoProjection(bool b) { - if(b) - camera()->setType(qglviewer::Camera::ORTHOGRAPHIC); - else - camera()->setType(qglviewer::Camera::PERSPECTIVE); + d->projection_is_ortho = b; update(); } -void Viewer::setOffset(qglviewer::Vec offset){ d->offset = offset; } -qglviewer::Vec Viewer::offset()const { return d->offset; } -void Viewer::setSceneBoundingBox(const qglviewer::Vec &min, const qglviewer::Vec &max) -{ - QGLViewer::setSceneBoundingBox(min+d->offset, max+d->offset); - d->drawGrid(camera()->sceneRadius()); -} - void Viewer::updateIds(CGAL::Three::Scene_item * item) { //all ids are computed when they are displayed the first time. @@ -1795,81 +1050,6 @@ void Viewer::enableClippingBox(QVector4D box[6]) d->clipbox[i] = box[i]; } - -bool Viewer::isOpenGL_4_3() const { return d->is_ogl_4_3; } -void Viewer_impl::drawGrid(qreal size, int nbSubdivisions) -{ - std::vector v_Grid; - std::vector v_gAxis; - std::vector n_gAxis; - std::vector c_gAxis; - for (int i=0; i<=nbSubdivisions; ++i) - { - const float pos = size*(2.0*i/nbSubdivisions-1.0); - v_Grid.push_back(pos); - v_Grid.push_back(-size); - v_Grid.push_back(0.0); - - v_Grid.push_back(pos); - v_Grid.push_back(+size); - v_Grid.push_back(0.0); - - v_Grid.push_back(-size); - v_Grid.push_back(pos); - v_Grid.push_back(0.0); - - v_Grid.push_back( size); - v_Grid.push_back( pos); - v_Grid.push_back( 0.0); - } - rendering_program_dist.bind(); - vao[2].bind(); - buffers[4].bind(); - buffers[4].allocate(v_Grid.data(),static_cast(v_Grid.size()*sizeof(float))); - rendering_program_dist.enableAttributeArray("vertex"); - rendering_program_dist.setAttributeBuffer("vertex",GL_FLOAT,0,3); - buffers[4].release(); - vao[2].release(); - rendering_program_dist.release(); - grid_size = v_Grid.size(); - - Viewer_impl::AxisData data; - v_gAxis.resize(0); - n_gAxis.resize(0); - c_gAxis.resize(0); - data.vertices = &v_gAxis; - data.normals = &n_gAxis; - data.colors = &c_gAxis; - makeArrow(0.02*size,10, qglviewer::Vec(0,0,0),qglviewer::Vec(size,0,0),qglviewer::Vec(1,0,0), data); - makeArrow(0.02*size,10, qglviewer::Vec(0,0,0),qglviewer::Vec(0,size,0),qglviewer::Vec(0,1,0), data); - makeArrow(0.02*size,10, qglviewer::Vec(0,0,0),qglviewer::Vec(0,0,size),qglviewer::Vec(0,0,1), data); - - rendering_program.bind(); - vao[3].bind(); - buffers[5].bind(); - buffers[5].allocate(v_gAxis.data(), static_cast(v_gAxis.size()) * sizeof(float)); - rendering_program.enableAttributeArray("vertex"); - rendering_program.setAttributeBuffer("vertex",GL_FLOAT,0,3); - buffers[5].release(); - - buffers[6].bind(); - buffers[6].allocate(n_gAxis.data(), static_cast(n_gAxis.size() * sizeof(float))); - rendering_program.enableAttributeArray("normal"); - rendering_program.setAttributeBuffer("normal",GL_FLOAT,0,3); - buffers[6].release(); - - buffers[7].bind(); - buffers[7].allocate(c_gAxis.data(), static_cast(c_gAxis.size() * sizeof(float))); - rendering_program.enableAttributeArray("colors"); - rendering_program.setAttributeBuffer("colors",GL_FLOAT,0,3); - buffers[7].release(); - vao[3].release(); - - rendering_program.release(); - - v_gaxis_size = v_gAxis.size(); - -} QOpenGLFunctions_4_3_Compatibility* Viewer::openGL_4_3_functions() { return d->_recentFunctions; } void Viewer::set2DSelectionMode(bool b) { d->is_2d_selection_mode = b; } @@ -1878,6 +1058,67 @@ void Viewer::setStaticImage(QImage image) { d->static_image = image; } const QImage& Viewer:: staticImage() const { return d->static_image; } +void Viewer::messageLogged(QOpenGLDebugMessage msg) +{ + QString error; + // Format based on severity + switch (msg.severity()) + { + case QOpenGLDebugMessage::NotificationSeverity: + return; + break; + case QOpenGLDebugMessage::HighSeverity: + error += "GL ERROR :"; + break; + case QOpenGLDebugMessage::MediumSeverity: + error += "GL WARNING :"; + break; + case QOpenGLDebugMessage::LowSeverity: + error += "GL NOTE :"; + break; + default: + break; + } -#include "Viewer.moc" + error += " ("; + + // Format based on source +#define CASE(c) case QOpenGLDebugMessage::c: error += #c; break + switch (msg.source()) + { + CASE(APISource); + CASE(WindowSystemSource); + CASE(ShaderCompilerSource); + CASE(ThirdPartySource); + CASE(ApplicationSource); + CASE(OtherSource); + CASE(InvalidSource); + default: + break; + } +#undef CASE + + error += " : "; + + // Format based on type +#define CASE(c) case QOpenGLDebugMessage::c: error += #c; break + switch (msg.type()) + { + CASE(ErrorType); + CASE(DeprecatedBehaviorType); + CASE(UndefinedBehaviorType); + CASE(PortabilityType); + CASE(PerformanceType); + CASE(OtherType); + CASE(MarkerType); + CASE(GroupPushType); + CASE(GroupPopType); + default: + break; + } +#undef CASE + + error += ")"; + qDebug() << qPrintable(error) << "\n" << qPrintable(msg.message()) << "\n"; +} diff --git a/Polyhedron/demo/Polyhedron/Viewer.h b/Polyhedron/demo/Polyhedron/Viewer.h index e104622dc1d..5d636d98775 100644 --- a/Polyhedron/demo/Polyhedron/Viewer.h +++ b/Polyhedron/demo/Polyhedron/Viewer.h @@ -6,11 +6,10 @@ #include #include #include +#include #include #include #include - -#include #include #include #include @@ -38,7 +37,7 @@ public: ~Viewer(); bool testDisplayId(double, double, double)Q_DECL_OVERRIDE; void updateIds(CGAL::Three::Scene_item *)Q_DECL_OVERRIDE; - //! overload several QGLViewer virtual functions + //! overload several CGAL::QGLViewer virtual functions //! Draws the scene. void draw()Q_DECL_OVERRIDE; //!This step happens after draw(). It is here that all the useful information is displayed, like the axis system or the informative text. @@ -47,7 +46,7 @@ public: void fastDraw()Q_DECL_OVERRIDE; bool isExtensionFound()Q_DECL_OVERRIDE; //! Initializes the OpenGL functions and sets the backGround color. - void initializeGL()Q_DECL_OVERRIDE; + void init()Q_DECL_OVERRIDE; //! Draws the scene "with names" to allow picking. void drawWithNames()Q_DECL_OVERRIDE; /*! Uses the parameter pixel's coordinates to get the corresponding point @@ -76,10 +75,7 @@ public: const char* v_shader, const char* f_shader)const; QPainter* getPainter()Q_DECL_OVERRIDE; - void saveSnapshot(bool , bool overwrite = false); - void setOffset(qglviewer::Vec offset); - qglviewer::Vec offset()const Q_DECL_OVERRIDE; - void setSceneBoundingBox(const qglviewer::Vec &min, const qglviewer::Vec &max); + TextRenderer* textRenderer() Q_DECL_OVERRIDE; void enableClippingBox(QVector4D box[]) Q_DECL_OVERRIDE; @@ -114,24 +110,16 @@ public Q_SLOTS: void hideMessage(); void setBindingSelect() Q_DECL_OVERRIDE { -#if QGLVIEWER_VERSION >= 0x020501 - setMouseBinding(::Qt::ShiftModifier, ::Qt::LeftButton, SELECT); -#else - setMouseBinding(::Qt::SHIFT + ::Qt::LeftButton, SELECT); -#endif + setMouseBinding(::Qt::ShiftModifier, ::Qt::LeftButton, CGAL::qglviewer::SELECT); } virtual void setNoBinding() Q_DECL_OVERRIDE { -#if QGLVIEWER_VERSION >= 0x020501 - setMouseBinding(::Qt::ShiftModifier, ::Qt::LeftButton, NO_CLICK_ACTION); -#else - setMouseBinding(::Qt::SHIFT + ::Qt::LeftButton, NO_CLICK_ACTION); -#endif + setMouseBinding(::Qt::ShiftModifier, ::Qt::LeftButton, CGAL::qglviewer::NO_CLICK_ACTION); } + void messageLogged(QOpenGLDebugMessage); protected: - void postDraw()Q_DECL_OVERRIDE; void paintEvent(QPaintEvent *)Q_DECL_OVERRIDE; void paintGL()Q_DECL_OVERRIDE; @@ -146,15 +134,12 @@ protected: //!Defines the behaviour for the key release events void keyReleaseEvent(QKeyEvent *)Q_DECL_OVERRIDE; - void resizeGL(int w, int h)Q_DECL_OVERRIDE; - protected: friend class Viewer_impl; Viewer_impl* d; double prev_radius; public: - bool isOpenGL_4_3() const Q_DECL_OVERRIDE; QOpenGLFunctions_4_3_Compatibility* openGL_4_3_functions() Q_DECL_OVERRIDE; }; // end class Viewer diff --git a/Polyhedron/demo/Polyhedron/create_sphere.h b/Polyhedron/demo/Polyhedron/create_sphere.h index 32af267e33b..5b3d846be32 100644 --- a/Polyhedron/demo/Polyhedron/create_sphere.h +++ b/Polyhedron/demo/Polyhedron/create_sphere.h @@ -13,15 +13,18 @@ void create_flat_sphere(FLOAT R, { //The more small they are, the more precise the Sphere will be. // Must be divisors of 180 and 360. - const int rings=prec/2; - const int sectors=prec; + const float rings=float(prec)/2; + const float sectors=float(prec); const float to_rad = static_cast(CGAL_PI / 180.0); float T, P; float x[4],y[4],z[4]; + using std::cos; + using std::sin; + //Top of the sphere - for(int t=0; t<360; t+=sectors) + for(float t=0; t<360.f; t+=sectors) { positions_spheres.push_back(0); @@ -61,8 +64,8 @@ void create_flat_sphere(FLOAT R, } //Body of the sphere - for (int p=rings; p<180-rings; p+=rings) - for(int t=0; t<360; t+=sectors) + for (float p=rings; p<180.f-rings; p+=rings) + for(float t=0; t<360.f; t+=sectors) { //A P = p*to_rad; @@ -140,7 +143,7 @@ void create_flat_sphere(FLOAT R, } //Bottom of the sphere - for(int t=0; t<360; t+=sectors) + for(float t=0; t<360.f; t+=sectors) { positions_spheres.push_back(0); positions_spheres.push_back(0); @@ -190,8 +193,8 @@ void create_flat_and_wire_sphere(FLOAT R, { //The smaller they are, the more precise the Sphere will be. // Must be a divisor of 360 and 180. - const int rings=prec/2; - const int sectors=prec; + const float rings=float(prec)/2; + const float sectors=float(prec); const float to_rad = static_cast(CGAL_PI / 180.0); create_flat_sphere(R, positions_spheres, normals_spheres); @@ -199,8 +202,11 @@ void create_flat_and_wire_sphere(FLOAT R, float T, P; float x[4],y[4],z[4]; + using std::cos; + using std::sin; + //Top of the sphere - for(int t=0; t<360; t+=sectors) + for(float t=0; t<360; t+=sectors) { positions_wire_spheres.push_back(0); positions_wire_spheres.push_back(0); @@ -240,8 +246,8 @@ void create_flat_and_wire_sphere(FLOAT R, } //Body of the sphere - for (int p=rings; p<180-rings; p+=rings) - for(int t=0; t<360; t+=sectors) + for (float p=rings; p<180.f-rings; p+=rings) + for(float t=0; t<360.f; t+=sectors) { //A P = p*to_rad; @@ -315,7 +321,7 @@ void create_flat_and_wire_sphere(FLOAT R, } //Bottom of the sphere - for(int t=0; t<360; t+=sectors) + for(float t=0; t<360.f; t+=sectors) { P = (180-rings)*to_rad; T = t*to_rad; diff --git a/Polyhedron/demo/Polyhedron/include/CGAL/IO/read_surf_trianglemesh.h b/Polyhedron/demo/Polyhedron/include/CGAL/IO/read_surf_trianglemesh.h index 7a33c37ee5e..9c4c9041b0d 100644 --- a/Polyhedron/demo/Polyhedron/include/CGAL/IO/read_surf_trianglemesh.h +++ b/Polyhedron/demo/Polyhedron/include/CGAL/IO/read_surf_trianglemesh.h @@ -291,7 +291,7 @@ bool read_surf(std::istream& input, std::vector& output, converter(mesh, false/*insert_isolated_vertices*/); CGAL_assertion(PMP::remove_isolated_vertices(mesh) == 0); - CGAL_assertion(is_valid(mesh)); + CGAL_assertion(is_valid_polygon_mesh(mesh)); } // end loop on patches return true; diff --git a/Polyhedron/demo/Polyhedron/include/Point_set_3.h b/Polyhedron/demo/Polyhedron/include/Point_set_3.h index d4a58257a37..8697f75c2cf 100644 --- a/Polyhedron/demo/Polyhedron/include/Point_set_3.h +++ b/Polyhedron/demo/Polyhedron/include/Point_set_3.h @@ -561,7 +561,7 @@ namespace CGAL namespace Point_set_processing_3 { template - class GetFT<::Point_set_3 > + class GetFT< ::Point_set_3 > { public: typedef typename Kernel::FT type; diff --git a/Polyhedron/demo/Polyhedron/include/id_printing.h b/Polyhedron/demo/Polyhedron/include/id_printing.h index 2e97d36d2f6..f195eb97f53 100644 --- a/Polyhedron/demo/Polyhedron/include/id_printing.h +++ b/Polyhedron/demo/Polyhedron/include/id_printing.h @@ -116,14 +116,26 @@ bool find_primitive_id(const QPoint& point, { typedef typename CGAL::Kernel_traits::Kernel Traits; bool found = false; - qglviewer::Vec point_under = viewer->camera()->pointUnderPixel(point,found); - const qglviewer::Vec offset = static_cast(QGLViewer::QGLViewerPool().first())->offset(); + CGAL::qglviewer::Vec point_under = viewer->camera()->pointUnderPixel(point,found); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); //find clicked facet - qglviewer::Vec dir = point_under - viewer->camera()->position(); - const Point ray_origin(viewer->camera()->position().x - offset.x, - viewer->camera()->position().y - offset.y, - viewer->camera()->position().z - offset.z); + CGAL::qglviewer::Vec dir; + Point ray_origin; + if(viewer->camera()->type() == CGAL::qglviewer::Camera::PERSPECTIVE) + { + dir = point_under - viewer->camera()->position(); + ray_origin = Point(viewer->camera()->position().x - offset.x, + viewer->camera()->position().y - offset.y, + viewer->camera()->position().z - offset.z); + } + else + { + dir = viewer->camera()->viewDirection(); + ray_origin = Point(point_under.x - dir.x, + point_under.y - dir.y, + point_under.z - dir.z); + } const typename Traits::Vector_3 ray_dir(dir.x, dir.y, dir.z); const typename Traits::Ray_3 ray(ray_origin, ray_dir); @@ -169,7 +181,7 @@ void compute_displayed_ids(Mesh& mesh, CGAL::Three::Viewer_interface *viewer, const typename boost::graph_traits::face_descriptor& selected_fh, const Point& pt_under, - const qglviewer::Vec& offset, + const CGAL::qglviewer::Vec& offset, TextListItem* vitems, TextListItem* eitems, TextListItem* fitems, @@ -215,9 +227,9 @@ void compute_displayed_ids(Mesh& mesh, } } QVector3D point( - get(ppmap, displayed_vertices[0]).x() + offset.x, - get(ppmap, displayed_vertices[0]).y() + offset.y, - get(ppmap, displayed_vertices[0]).z() + offset.z); + float(get(ppmap, displayed_vertices[0]).x() + offset.x), + float(get(ppmap, displayed_vertices[0]).y() + offset.y), + float(get(ppmap, displayed_vertices[0]).z() + offset.z)); //test if we want to erase or not BOOST_FOREACH(TextItem* text_item, *targeted_ids) @@ -342,7 +354,10 @@ void compute_displayed_ids(Mesh& mesh, Point pos=Point(get(ppmap, vh).x()+offset.x, get(ppmap, vh).y()+offset.y, get(ppmap, vh).z()+offset.z); - TextItem* text_item = new TextItem(pos.x(), pos.y(), pos.z(), QString("%1").arg(get(vidmap, vh)), true, font, Qt::red); + TextItem* text_item = new TextItem(float(pos.x()), + float(pos.y()), + float(pos.z()), + QString("%1").arg(get(vidmap, vh)), true, font, Qt::red); vitems->append(text_item); targeted_ids->push_back(text_item); } @@ -354,7 +369,10 @@ void compute_displayed_ids(Mesh& mesh, pos.y()+offset.y, pos.z()+offset.z); - TextItem* text_item = new TextItem(pos.x(), pos.y(), pos.z(), QString("%1").arg(get(hidmap, h)/2), true, font, Qt::green); + TextItem* text_item = new TextItem(float(pos.x()), + float(pos.y()), + float(pos.z()), + QString("%1").arg(get(hidmap, h)/2), true, font, Qt::green); eitems->append(text_item); } @@ -373,7 +391,10 @@ void compute_displayed_ids(Mesh& mesh, Point pos(x/total+offset.x, y/total+offset.y, z/total+offset.z); - TextItem* text_item = new TextItem(pos.x(), pos.y(), pos.z(), QString("%1").arg(get(fidmap,f)), true, font, Qt::blue); + TextItem* text_item = new TextItem(float(pos.x()), + float(pos.y()), + float(pos.z()), + QString("%1").arg(get(fidmap,f)), true, font, Qt::blue); fitems->append(text_item); } } @@ -390,7 +411,7 @@ bool printVertexIds(const Mesh& mesh, Ppmap ppmap = get(boost::vertex_point, mesh); IDmap idmap = get(boost::vertex_index, mesh); TextRenderer *renderer = viewer->textRenderer(); - const qglviewer::Vec offset = viewer->offset(); + const CGAL::qglviewer::Vec offset = viewer->offset(); QFont font; font.setBold(true); @@ -398,9 +419,9 @@ bool printVertexIds(const Mesh& mesh, BOOST_FOREACH(typename boost::graph_traits::vertex_descriptor vh, vertices(mesh)) { const Point& p = get(ppmap, vh); - vitems->append(new TextItem((float)p.x() + offset.x, - (float)p.y() + offset.y, - (float)p.z() + offset.z, + vitems->append(new TextItem(float(p.x() + offset.x), + float(p.y() + offset.y), + float(p.z() + offset.z), QString("%1").arg(get(idmap, vh)), true, font, Qt::red)); } @@ -425,7 +446,7 @@ bool printEdgeIds(const Mesh& mesh, Ppmap ppmap = get(boost::vertex_point, mesh); IDmap idmap = get(boost::halfedge_index, mesh); TextRenderer *renderer = viewer->textRenderer(); - const qglviewer::Vec offset = viewer->offset(); + const CGAL::qglviewer::Vec offset = viewer->offset(); QFont font; font.setBold(true); @@ -433,9 +454,9 @@ bool printEdgeIds(const Mesh& mesh, { const Point& p1 = get(ppmap, source(e, mesh)); const Point& p2 = get(ppmap, target(e, mesh)); - eitems->append(new TextItem((float)(p1.x() + p2.x()) / 2 + offset.x, - (float)(p1.y() + p2.y()) / 2 + offset.y, - (float)(p1.z() + p2.z()) / 2 + offset.z, + eitems->append(new TextItem(float((p1.x() + p2.x()) / 2 + offset.x), + float((p1.y() + p2.y()) / 2 + offset.y), + float((p1.z() + p2.z()) / 2 + offset.z), QString("%1").arg(get(idmap, halfedge(e, mesh)) / 2), true, font, Qt::green)); } //add the QList to the render's pool @@ -458,24 +479,24 @@ bool printFaceIds(const Mesh& mesh, Ppmap ppmap = get(boost::vertex_point, mesh); IDmap idmap = get(boost::face_index, mesh); TextRenderer *renderer = viewer->textRenderer(); - const qglviewer::Vec offset = viewer->offset(); + const CGAL::qglviewer::Vec offset = viewer->offset(); QFont font; font.setBold(true); BOOST_FOREACH(typename boost::graph_traits::face_descriptor fh, faces(mesh)) { double x(0), y(0), z(0); - int total(0); + float total(0); BOOST_FOREACH(typename boost::graph_traits::vertex_descriptor vh, vertices_around_face(halfedge(fh, mesh), mesh)) { x += get(ppmap, vh).x(); y += get(ppmap, vh).y(); z += get(ppmap, vh).z(); - ++total; + total += 1.f; } - fitems->append(new TextItem((float)x / total + offset.x, - (float)y / total + offset.y, - (float)z / total + offset.z, + fitems->append(new TextItem(float(x / total + offset.x), + float(y / total + offset.y), + float(z / total + offset.z), QString("%1").arg(get(idmap, fh)), true, font, Qt::blue)); } //add the QList to the render's pool @@ -518,7 +539,7 @@ int zoomToId(const Mesh& mesh, { return 1; //("Input must be of the form [v/e/f][int]" } - const qglviewer::Vec offset = viewer->offset(); + const CGAL::qglviewer::Vec offset = viewer->offset(); typename Traits::Vector_3 normal; if(first == QString("v")) { @@ -599,24 +620,18 @@ int zoomToId(const Mesh& mesh, return 4; //"No face with id %1").arg(id) } } - qglviewer::Quaternion new_orientation(qglviewer::Vec(0,0,-1), - qglviewer::Vec(-normal.x(), -normal.y(), -normal.z())); + CGAL::qglviewer::Quaternion new_orientation(CGAL::qglviewer::Vec(0,0,-1), + CGAL::qglviewer::Vec(-normal.x(), -normal.y(), -normal.z())); Point new_pos = p + - qglviewer::Vec( + CGAL::qglviewer::Vec( viewer->camera()->position().x - viewer->camera()->sceneCenter().x, viewer->camera()->position().y - viewer->camera()->sceneCenter().y, viewer->camera()->position().z - viewer->camera()->sceneCenter().z) .norm() * normal ; -#if QGLVIEWER_VERSION >= 0x020502 - viewer->camera()->setPivotPoint(qglviewer::Vec(p.x(), + viewer->camera()->setPivotPoint(CGAL::qglviewer::Vec(p.x(), p.y(), p.z())); -#else - viewer->camera()->setRevolveAroundPoint(qglviewer::Vec(p.x(), - p.y(), - p.z())); -#endif viewer->moveCameraToCoordinates(QString("%1 %2 %3 %4 %5 %6 %7").arg(new_pos.x()) .arg(new_pos.y()) diff --git a/Polyhedron/demo/Polyhedron/triangulate_primitive.h b/Polyhedron/demo/Polyhedron/triangulate_primitive.h index 55e737aad24..0d5e2c915eb 100644 --- a/Polyhedron/demo/Polyhedron/triangulate_primitive.h +++ b/Polyhedron/demo/Polyhedron/triangulate_primitive.h @@ -50,15 +50,16 @@ public: //Constructor FacetTriangulator(typename boost::graph_traits::face_descriptor fd, - const Vector& normal, + const Vector& normal, Mesh *poly, - const double item_diag) + const double item_diag, + Vector offset = Vector(0,0,0)) { std::vector idPoints; BOOST_FOREACH(halfedge_descriptor he_circ, halfedges_around_face( halfedge(fd, *poly), *poly)) { PointAndId idPoint; - idPoint.point = get(boost::vertex_point,*poly,source(he_circ, *poly)); + idPoint.point = get(boost::vertex_point,*poly,source(he_circ, *poly))+offset; idPoint.id = source(he_circ, *poly); idPoints.push_back(idPoint); @@ -70,13 +71,14 @@ public: const std::vector& more_points, const Vector& normal, Mesh *poly, - const double item_diag) + const double item_diag, + Vector offset = Vector(0,0,0)) { std::vector idPoints; BOOST_FOREACH(halfedge_descriptor he_circ, halfedges_around_face( halfedge(fd, *poly), *poly)) { PointAndId idPoint; - idPoint.point = get(boost::vertex_point,*poly,source(he_circ, *poly)); + idPoint.point = get(boost::vertex_point,*poly,source(he_circ, *poly))+offset; idPoint.id = source(he_circ, *poly); idPoints.push_back(idPoint); diff --git a/Polyhedron/doc/Polyhedron/CGAL/draw_polyhedron.h b/Polyhedron/doc/Polyhedron/CGAL/draw_polyhedron.h new file mode 100644 index 00000000000..8ac1c401b79 --- /dev/null +++ b/Polyhedron/doc/Polyhedron/CGAL/draw_polyhedron.h @@ -0,0 +1,15 @@ +namespace CGAL { + +/*! +\ingroup PkgDrawPolyhedron + +Open a new window and draw `apoly`, an instance of the `CGAL::Polyhedron_3` class. The function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. +\tparam POLY an instance of the `CGAL::Polyhedron_3` class. +\param apoly the polyhedron to draw. + +*/ +template +void draw(const POLY& apoly); + +} /* namespace CGAL */ + diff --git a/Polyhedron/doc/Polyhedron/PackageDescription.txt b/Polyhedron/doc/Polyhedron/PackageDescription.txt index aa9cf8ed001..05972f40034 100644 --- a/Polyhedron/doc/Polyhedron/PackageDescription.txt +++ b/Polyhedron/doc/Polyhedron/PackageDescription.txt @@ -4,6 +4,15 @@ /// \defgroup PkgPolyhedronIOFunc I/O Functions /// \ingroup PkgPolyhedron + +/*! Draw. + \code + #include + \endcode +*/ +/// \defgroup PkgDrawPolyhedron Draw a Polyhedron 3 +/// \ingroup PkgPolyhedron + /*! \addtogroup PkgPolyhedron \todo check generated documentation @@ -62,5 +71,9 @@ surface can be used without knowing the halfedge data structure. - \link PkgPolyhedronIOFunc `CGAL::operator>>()` \endlink - \link PkgPolyhedronIOFunc `write_off()` \endlink - \link PkgPolyhedronIOFunc `read_off()` \endlink + +### Draw a Polyhedron 3 ### +- `CGAL::draw` + */ diff --git a/Polyhedron/doc/Polyhedron/Polyhedron.txt b/Polyhedron/doc/Polyhedron/Polyhedron.txt index 7e39194363e..b960089fa00 100644 --- a/Polyhedron/doc/Polyhedron/Polyhedron.txt +++ b/Polyhedron/doc/Polyhedron/Polyhedron.txt @@ -275,6 +275,19 @@ are also marked in the program code. \cgalExample{Polyhedron/polyhedron_prog_cube.cpp} +\subsection PolyhedronDraw Draw a Polyhedron +\anchor ssecDrawPolyhedron + +A polyhedron can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given polyhedron. The function is blocking, that is the program continues as soon as the user closes the window. + +\cgalExample{Polyhedron/draw_polyhedron.cpp} + +This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. + +\cgalFigureBegin{fig_draw_polyhedron,draw_polyhedron.png} +Result of the run of the draw_polyhedron program. A window shows the polyhedron and allows to navigate through the 3D scene. +\cgalFigureEnd + \section PolyhedronFile File I/O \anchor sectionPolyIO diff --git a/Polyhedron/doc/Polyhedron/examples.txt b/Polyhedron/doc/Polyhedron/examples.txt index 8fc56694e39..e106785f37d 100644 --- a/Polyhedron/doc/Polyhedron/examples.txt +++ b/Polyhedron/doc/Polyhedron/examples.txt @@ -10,4 +10,5 @@ \example Polyhedron/polyhedron_prog_subdiv.cpp \example Polyhedron/polyhedron_prog_tetra.cpp \example Polyhedron/polyhedron_prog_vector.cpp +\example Polyhedron/draw_polyhedron.cpp */ diff --git a/Polyhedron/doc/Polyhedron/fig/draw_polyhedron.png b/Polyhedron/doc/Polyhedron/fig/draw_polyhedron.png new file mode 100644 index 00000000000..0d711aef842 Binary files /dev/null and b/Polyhedron/doc/Polyhedron/fig/draw_polyhedron.png differ diff --git a/Polyhedron/examples/Polyhedron/CMakeLists.txt b/Polyhedron/examples/Polyhedron/CMakeLists.txt index f2b82769342..d191da8a473 100644 --- a/Polyhedron/examples/Polyhedron/CMakeLists.txt +++ b/Polyhedron/examples/Polyhedron/CMakeLists.txt @@ -4,9 +4,18 @@ project( Polyhedron_Examples ) -cmake_minimum_required(VERSION 2.8.10) +cmake_minimum_required(VERSION 3.1) -find_package(CGAL QUIET) +if(NOT POLICY CMP0070 AND POLICY CMP0053) + # Only set CMP0053 to OLD with CMake<3.10, otherwise there is a warning. + cmake_policy(SET CMP0053 OLD) +endif() + +find_package(CGAL COMPONENTS Qt5) + +if(CGAL_Qt5_FOUND) + add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS) +endif() if ( CGAL_FOUND ) @@ -16,12 +25,17 @@ if ( CGAL_FOUND ) include_directories (BEFORE "../../include") + # create a target per cppfile file(GLOB cppfiles RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) foreach(cppfile ${cppfiles}) create_single_source_cgal_program( "${cppfile}" ) endforeach() + if(CGAL_Qt5_FOUND ) + target_link_libraries(draw_polyhedron PUBLIC CGAL::CGAL_Qt5) + endif() + else() message(STATUS "This program requires the CGAL library, and will not be compiled.") diff --git a/Polyhedron/examples/Polyhedron/corner.off b/Polyhedron/examples/Polyhedron/data/corner.off similarity index 100% rename from Polyhedron/examples/Polyhedron/corner.off rename to Polyhedron/examples/Polyhedron/data/corner.off diff --git a/Polyhedron/examples/Polyhedron/corner_with_hole.off b/Polyhedron/examples/Polyhedron/data/corner_with_hole.off similarity index 100% rename from Polyhedron/examples/Polyhedron/corner_with_hole.off rename to Polyhedron/examples/Polyhedron/data/corner_with_hole.off diff --git a/Polyhedron/examples/Polyhedron/corner_with_sharp_edge.off b/Polyhedron/examples/Polyhedron/data/corner_with_sharp_edge.off similarity index 100% rename from Polyhedron/examples/Polyhedron/corner_with_sharp_edge.off rename to Polyhedron/examples/Polyhedron/data/corner_with_sharp_edge.off diff --git a/Polyhedron/examples/Polyhedron/cross.off b/Polyhedron/examples/Polyhedron/data/cross.off similarity index 100% rename from Polyhedron/examples/Polyhedron/cross.off rename to Polyhedron/examples/Polyhedron/data/cross.off diff --git a/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv.cin b/Polyhedron/examples/Polyhedron/data/cube.off similarity index 100% rename from Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv.cin rename to Polyhedron/examples/Polyhedron/data/cube.off diff --git a/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv_with_boundary.cin b/Polyhedron/examples/Polyhedron/data/lshape_with_boundary.off similarity index 100% rename from Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv_with_boundary.cin rename to Polyhedron/examples/Polyhedron/data/lshape_with_boundary.off diff --git a/Polyhedron/examples/Polyhedron/polyhedron_self_intersection.cin b/Polyhedron/examples/Polyhedron/data/tetra_intersected_by_triangle.off similarity index 100% rename from Polyhedron/examples/Polyhedron/polyhedron_self_intersection.cin rename to Polyhedron/examples/Polyhedron/data/tetra_intersected_by_triangle.off diff --git a/Polyhedron/examples/Polyhedron/draw_polyhedron.cpp b/Polyhedron/examples/Polyhedron/draw_polyhedron.cpp new file mode 100644 index 00000000000..a41fc79cc02 --- /dev/null +++ b/Polyhedron/examples/Polyhedron/draw_polyhedron.cpp @@ -0,0 +1,18 @@ +#include +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef CGAL::Polyhedron_3 Polyhedron; + +int main(int argc, char* argv[]) +{ + Polyhedron P; + std::ifstream in1((argc>1)?argv[1]:"data/cross.off"); + in1 >> P; + CGAL::draw(P); + + return EXIT_SUCCESS; +} diff --git a/Polyhedron/examples/Polyhedron/polyhedron_prog_cut_cube.cpp b/Polyhedron/examples/Polyhedron/polyhedron_prog_cut_cube.cpp index 74dcfff094a..c244c1c1c74 100644 --- a/Polyhedron/examples/Polyhedron/polyhedron_prog_cut_cube.cpp +++ b/Polyhedron/examples/Polyhedron/polyhedron_prog_cut_cube.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include diff --git a/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv.cpp b/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv.cpp index 009841ff69a..b7d997bcfc1 100644 --- a/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv.cpp +++ b/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv.cpp @@ -1,10 +1,10 @@ #include #include -#include #include #include #include #include +#include typedef CGAL::Simple_cartesian Kernel; typedef Kernel::Vector_3 Vector; @@ -91,9 +91,10 @@ void subdiv( Polyhedron& P) { CGAL_postcondition( P.is_valid()); } -int main() { +int main(int argc, char* argv[]) { Polyhedron P; - std::cin >> P; + std::ifstream in1((argc>1)?argv[1]:"data/cube.off"); + in1 >> P; P.normalize_border(); if ( P.size_of_border_edges() != 0) { std::cerr << "The input object has border edges. Cannot subdivide." diff --git a/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv_with_boundary.cpp b/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv_with_boundary.cpp index 90ead40b2ff..296c910239a 100644 --- a/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv_with_boundary.cpp +++ b/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv_with_boundary.cpp @@ -1,12 +1,12 @@ #include #include -#include #include #include #include #include #include #include +#include typedef CGAL::Simple_cartesian Kernel; typedef Kernel::Vector_3 Vector; @@ -173,21 +173,22 @@ void subdiv_border( Polyhedron& P) { using namespace std; int main( int argc, char* argv[]) { - if ( argc > 2 || (argc == 2 && ! isdigit( argv[1][0]))) { - cerr << "Usage: " << argv[0] << " []" << endl; - cerr << " subdivides times the polyhedron read from stdin." + if ( argc > 3 || (argc == 3 && ! isdigit( argv[2][0]))) { + cerr << "Usage: " << argv[0] << " [offfile] []]" << endl; + cerr << " subdivides times the polyhedron read from offfile." << endl; exit(1); } int n = 1; - if ( argc >= 2) - n = atoi( argv[1]); + std::ifstream in1((argc>1)?argv[1]:"data/lshape_with_boundary.off"); + if ( argc == 3) + n = atoi( argv[2]); if ( n < 1 || n > 12) { cerr << "Error: Choose reasonable value for in [1..12]" << endl; exit(1); } Polyhedron P; - cin >> P; + in1 >> P; for ( int i = 0; i != n; ++i) { cerr << "Subdivision " << i+1 << " ..." << endl; diff --git a/Polyhedron/examples/Polyhedron/polyhedron_self_intersection.cpp b/Polyhedron/examples/Polyhedron/polyhedron_self_intersection.cpp index 5bea593eaa1..5bfc3f0ced6 100644 --- a/Polyhedron/examples/Polyhedron/polyhedron_self_intersection.cpp +++ b/Polyhedron/examples/Polyhedron/polyhedron_self_intersection.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -8,6 +7,7 @@ #include #include #include +#include using std::cerr; using std::endl; @@ -139,12 +139,13 @@ void intersection( const Polyhedron& P) { Intersect_facets(), std::ptrdiff_t(2000)); } -int main() { +int main(int argc, char* argv[]) { CGAL::Timer user_time; cerr << "Loading OFF file ... " << endl; user_time.start(); Polyhedron P; - cin >> P; + std::ifstream in1((argc>1)?argv[1]:"data/tetra_intersected_by_triangle.off"); + in1 >> P; cerr << "Loading OFF file : " << user_time.time() << " seconds." << endl; if ( ! P.is_pure_triangle()) { cerr << "The input object is not triangulated. Cannot intersect." @@ -156,5 +157,6 @@ int main() { intersection( P); cerr << "Intersection : " << user_time.time() << " seconds." << endl; write_off(); + return 0; } diff --git a/Polyhedron/include/CGAL/boost/graph/graph_traits_Polyhedron_3.h b/Polyhedron/include/CGAL/boost/graph/graph_traits_Polyhedron_3.h index 3d1c005e3bc..89c572d690d 100644 --- a/Polyhedron/include/CGAL/boost/graph/graph_traits_Polyhedron_3.h +++ b/Polyhedron/include/CGAL/boost/graph/graph_traits_Polyhedron_3.h @@ -463,12 +463,6 @@ reserve(CGAL::Polyhedron_3& p, p.reserve(nv, 2*ne, nf); } -template -bool is_valid(const CGAL::Polyhedron_3& p, bool verbose = false) -{ - return p.is_valid(verbose); -} - template void normalize_border(CGAL::Polyhedron_3& p) { diff --git a/Polyhedron/include/CGAL/draw_polyhedron.h b/Polyhedron/include/CGAL/draw_polyhedron.h new file mode 100644 index 00000000000..b8464757097 --- /dev/null +++ b/Polyhedron/include/CGAL/draw_polyhedron.h @@ -0,0 +1,240 @@ +// Copyright (c) 2018 ETH Zurich (Switzerland). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// Author(s) : Guillaume Damiand + +#ifndef CGAL_DRAW_POLYHEDRON_H +#define CGAL_DRAW_POLYHEDRON_H + +#include +#include + +#ifdef CGAL_USE_BASIC_VIEWER + +#include + +namespace CGAL +{ + +// Default color functor; user can change it to have its own face color +struct DefaultColorFunctorPolyhedron +{ + template + static CGAL::Color run(const Polyhedron&, + typename Polyhedron::Facet_const_handle fh) + { + if (fh==boost::graph_traits::null_face()) // use to get the mono color + return CGAL::Color(100, 125, 200); // R G B between 0-255 + + CGAL::Random random((unsigned int)(std::size_t)(&(*fh))); + return get_random_color(random); + } +}; + +// Viewer class for Polyhedron +template +class SimplePolyhedronViewerQt : public Basic_viewer_qt +{ + typedef Basic_viewer_qt Base; + typedef typename Polyhedron::Traits Kernel; + typedef typename Polyhedron::Halfedge_const_handle Halfedge_const_handle; + typedef typename Polyhedron::Vertex_const_handle Vertex_const_handle; + typedef typename Polyhedron::Facet_const_handle Facet_const_handle; + +public: + /// Construct the viewer. + /// @param apoly the polyhedron to view + /// @param title the title of the window + /// @param anofaces if true, do not draw faces (faces are not computed; this can be + /// usefull for very big object where this time could be long) + SimplePolyhedronViewerQt(QWidget* parent, + const Polyhedron& apoly, + const char* title="Basic Polyhedron Viewer", + bool anofaces=false, + const ColorFunctor& fcolor=ColorFunctor()) : + // First draw: no vertex; edges, faces; mono-color; inverse normal + Base(parent, title, false, true, true, true, false), + poly(apoly), + m_nofaces(anofaces), + m_fcolor(fcolor) + { + compute_elements(); + } + +protected: + void compute_face(Facet_const_handle fh) + { + CGAL::Color c=m_fcolor.run(poly, fh); + face_begin(c); + Halfedge_const_handle he=fh->facet_begin(); + do + { + add_point_in_face(he->vertex()->point(), + get_vertex_normal(he)); + he=he->next(); + } + while (he!=fh->facet_begin()); + face_end(); + } + + void compute_edge(Halfedge_const_handle he) + { + add_segment(he->vertex()->point(), + he->opposite()->vertex()->point()); + // We can use add_segment(p1, p2, c) with c a CGAL::Color to add a colored segment + } + + void compute_vertex(Vertex_const_handle vh) + { + add_point(vh->point()); + // We can use add_point(p, c) with c a CGAL::Color to add a colored point + } + + void compute_elements() + { + clear(); + + if (!m_nofaces) + { + for(typename Polyhedron::Facet_const_iterator f=poly.facets_begin(); + f!=poly.facets_end(); f++) + { + if (f!=boost::graph_traits::null_face()) + { compute_face(f); } + } + } + + for ( typename Polyhedron::Halfedge_const_iterator e=poly.halfedges_begin(); + e!=poly.halfedges_end(); ++e) + { + if (eopposite()) + { compute_edge(e); } + } + + for ( typename Polyhedron::Vertex_const_iterator v=poly.vertices_begin(); + v!=poly.vertices_end(); ++v) + { compute_vertex(v); } + } + + virtual void keyPressEvent(QKeyEvent *e) + { + // Test key pressed: + // const ::Qt::KeyboardModifiers modifiers = e->modifiers(); + // if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) { ... } + + // Call: * compute_elements() if the model changed, followed by + // * redraw() if some viewing parameters changed that implies some + // modifications of the buffers + // (eg. type of normal, color/mono) + // * update() just to update the drawing + + // Call the base method to process others/classicals key + Base::keyPressEvent(e); + } + +protected: + typename Kernel::Vector_3 get_face_normal(Halfedge_const_handle he) + { + typename Kernel::Vector_3 normal=CGAL::NULL_VECTOR; + Halfedge_const_handle end=he; + unsigned int nb=0; + do + { + internal::newell_single_step_3(he->vertex()->point(), + he->next()->vertex()->point(), + normal); + ++nb; + he=he->next(); + } + while (he!=end); + assert(nb>0); + return (typename Kernel::Construct_scaled_vector_3()(normal, 1.0/nb)); + } + + typename Kernel::Vector_3 get_vertex_normal(Halfedge_const_handle he) + { + typename Kernel::Vector_3 normal=CGAL::NULL_VECTOR; + Halfedge_const_handle end=he; + do + { + if (!he->is_border()) + { + typename Kernel::Vector_3 n=get_face_normal(he); + normal=typename Kernel::Construct_sum_of_vectors_3()(normal, n); + } + he=he->next()->opposite(); + } + while (he!=end); + + if (!typename Kernel::Equal_3()(normal, CGAL::NULL_VECTOR)) + { normal=(typename Kernel::Construct_scaled_vector_3() + (normal, 1.0/CGAL::sqrt(normal.squared_length()))); } + + return normal; + } + +protected: + const Polyhedron& poly; + bool m_nofaces; + const ColorFunctor& m_fcolor; +}; + +template +void draw(const Polyhedron& apoly, + const char* title, + bool nofill, + const ColorFunctor& fcolor) +{ +#if defined(CGAL_TEST_SUITE) + bool cgal_test_suite=true; +#else + bool cgal_test_suite=false; +#endif + + if (!cgal_test_suite) + { + int argc=1; + const char* argv[2]={"polyhedron_viewer","\0"}; + QApplication app(argc,const_cast(argv)); + SimplePolyhedronViewerQt + mainwindow(app.activeWindow(), apoly, title, nofill, fcolor); + mainwindow.show(); + app.exec(); + } +} + +template +void draw(const Polyhedron& apoly, const char* title, bool nofill) +{ + DefaultColorFunctorPolyhedron c; + draw(apoly, title, nofill, c); +} + +template +void draw(const Polyhedron& apoly, const char* title) +{ draw(apoly, title, false); } + +template +void draw(const Polyhedron& apoly) +{ draw(apoly, "Basic Polyhedron Viewer"); } + +} // End namespace CGAL + +#endif // CGAL_USE_BASIC_VIEWER + +#endif // CGAL_DRAW_POLYHEDRON_H diff --git a/Polyhedron/package_info/Polyhedron/dependencies b/Polyhedron/package_info/Polyhedron/dependencies index 47699a9637a..70c007e409d 100644 --- a/Polyhedron/package_info/Polyhedron/dependencies +++ b/Polyhedron/package_info/Polyhedron/dependencies @@ -2,6 +2,7 @@ Algebraic_foundations BGL Circulator Distance_2 +GraphicsView HalfedgeDS Hash_map Installation diff --git a/Polyhedron/test/Polyhedron/bug_polyhedron_incremental_builder_3.cpp b/Polyhedron/test/Polyhedron/bug_polyhedron_incremental_builder_3.cpp index 17ead1f548f..df51270184b 100644 --- a/Polyhedron/test/Polyhedron/bug_polyhedron_incremental_builder_3.cpp +++ b/Polyhedron/test/Polyhedron/bug_polyhedron_incremental_builder_3.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include typedef CGAL::Simple_cartesian K; diff --git a/Polyhedron_IO/examples/Polyhedron_IO/off2stl.cpp b/Polyhedron_IO/examples/Polyhedron_IO/off2stl.cpp index 71e2c2b7723..0419f5e218e 100644 --- a/Polyhedron_IO/examples/Polyhedron_IO/off2stl.cpp +++ b/Polyhedron_IO/examples/Polyhedron_IO/off2stl.cpp @@ -2,7 +2,6 @@ #include #include -#include #include #include #include diff --git a/Polyhedron_IO/examples/Polyhedron_IO/polyhedron2vrml.cpp b/Polyhedron_IO/examples/Polyhedron_IO/polyhedron2vrml.cpp index a2466f354e1..f6431fd9b57 100644 --- a/Polyhedron_IO/examples/Polyhedron_IO/polyhedron2vrml.cpp +++ b/Polyhedron_IO/examples/Polyhedron_IO/polyhedron2vrml.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include diff --git a/Polyhedron_IO/examples/Polyhedron_IO/polyhedron_copy.cpp b/Polyhedron_IO/examples/Polyhedron_IO/polyhedron_copy.cpp index b192f224fe5..f93cd531db5 100644 --- a/Polyhedron_IO/examples/Polyhedron_IO/polyhedron_copy.cpp +++ b/Polyhedron_IO/examples/Polyhedron_IO/polyhedron_copy.cpp @@ -2,7 +2,6 @@ #include #include -#include #include #include #include diff --git a/Polyhedron_IO/test/Polyhedron_IO/test_polyhedron_io.cpp b/Polyhedron_IO/test/Polyhedron_IO/test_polyhedron_io.cpp index 181062a7990..f737d11d10f 100644 --- a/Polyhedron_IO/test/Polyhedron_IO/test_polyhedron_io.cpp +++ b/Polyhedron_IO/test/Polyhedron_IO/test_polyhedron_io.cpp @@ -32,7 +32,6 @@ // disabled compilers. #ifndef CGAL_USE_POLYHEDRON_DESIGN_ONE -#include #include #include #include diff --git a/Polynomial/include/CGAL/Polynomial/Algebraic_structure_traits.h b/Polynomial/include/CGAL/Polynomial/Algebraic_structure_traits.h index 3d3bc87cbb5..4e3cd937533 100644 --- a/Polynomial/include/CGAL/Polynomial/Algebraic_structure_traits.h +++ b/Polynomial/include/CGAL/Polynomial/Algebraic_structure_traits.h @@ -88,7 +88,7 @@ class Polynomial_algebraic_structure_traits_base< POLY, typedef Integral_domain_without_division_tag Algebraic_category; class Simplify - : public CGAL::unary_function< POLY&, void > { + : public CGAL::cpp98::unary_function< POLY&, void > { public: void operator()( POLY& p ) const { p.simplify_coefficients(); @@ -96,7 +96,7 @@ class Polynomial_algebraic_structure_traits_base< POLY, }; class Unit_part - : public CGAL::unary_function< POLY, POLY > { + : public CGAL::cpp98::unary_function< POLY, POLY > { public: POLY operator()( const POLY& x ) const { return POLY( x.unit_part() ); @@ -104,7 +104,7 @@ class Polynomial_algebraic_structure_traits_base< POLY, }; class Is_zero - : public CGAL::unary_function< POLY, bool > { + : public CGAL::cpp98::unary_function< POLY, bool > { public: bool operator()( const POLY& x ) const { return x.is_zero(); @@ -122,7 +122,7 @@ class Polynomial_algebraic_structure_traits_base< POLY, Integral_domain_tag > typedef Integral_domain_tag Algebraic_category; class Integral_division - : public CGAL::binary_function< POLY, POLY, POLY > { + : public CGAL::cpp98::binary_function< POLY, POLY, POLY > { public: POLY operator()( const POLY& x, const POLY& y ) const { return x / y; @@ -136,7 +136,7 @@ private: typedef typename Divides_coeff::result_type BOOL; public: class Divides - : public CGAL::binary_function{ + : public CGAL::cpp98::binary_function{ public: BOOL operator()( const POLY& p1, const POLY& p2) const { POLY q; @@ -210,7 +210,7 @@ class Polynomial_algebraic_structure_traits_base< POLY, Unique_factorization_dom typedef Unique_factorization_domain_tag Algebraic_category; class Gcd - : public CGAL::binary_function< POLY, POLY, POLY > { + : public CGAL::cpp98::binary_function< POLY, POLY, POLY > { typedef typename Polynomial_traits_d::Multivariate_content Mcontent; typedef typename Mcontent::result_type ICoeff; @@ -293,7 +293,7 @@ class Polynomial_algebraic_structure_traits_base< POLY, Field_tag > }; class Div - : public CGAL::binary_function< POLY, POLY, POLY > { + : public CGAL::cpp98::binary_function< POLY, POLY, POLY > { public: POLY operator()(const POLY& a, const POLY& b) const { POLY q, r; @@ -305,7 +305,7 @@ class Polynomial_algebraic_structure_traits_base< POLY, Field_tag > }; class Mod - : public CGAL::binary_function< POLY, POLY, POLY > { + : public CGAL::cpp98::binary_function< POLY, POLY, POLY > { public: POLY operator () (const POLY& a, const POLY& b) const { POLY q, r; diff --git a/Polynomial/include/CGAL/Polynomial/Degree.h b/Polynomial/include/CGAL/Polynomial/Degree.h index 186c27a83a1..bc1b85c9c40 100644 --- a/Polynomial/include/CGAL/Polynomial/Degree.h +++ b/Polynomial/include/CGAL/Polynomial/Degree.h @@ -38,7 +38,7 @@ template struct Degree; // Polynomial musst be at least univariate ! template struct Degree > - : public CGAL::unary_function< Polynomial , int >{ + : public CGAL::cpp98::unary_function< Polynomial , int >{ private: typedef Polynomial Polynomial_d; diff --git a/Polynomial/include/CGAL/Polynomial_traits_d.h b/Polynomial/include/CGAL/Polynomial_traits_d.h index 42c96b05c15..a7de7bdea44 100644 --- a/Polynomial/include/CGAL/Polynomial_traits_d.h +++ b/Polynomial/include/CGAL/Polynomial_traits_d.h @@ -123,7 +123,7 @@ public: struct Multivariate_content - : public CGAL::unary_function< Polynomial_d , Innermost_coefficient_type >{ + : public CGAL::cpp98::unary_function< Polynomial_d , Innermost_coefficient_type >{ Innermost_coefficient_type operator()(const Polynomial_d& p) const { typedef Innermost_coefficient_const_iterator IT; @@ -156,7 +156,7 @@ public: // Multivariate_content; struct Multivariate_content - : public CGAL::unary_function< Polynomial_d , Innermost_coefficient_type >{ + : public CGAL::cpp98::unary_function< Polynomial_d , Innermost_coefficient_type >{ Innermost_coefficient_type operator()(const Polynomial_d& p) const { if( CGAL::is_zero(p) ) return Innermost_coefficient_type(0); @@ -217,7 +217,7 @@ public: // Univariate_content struct Univariate_content - : public CGAL::unary_function< Polynomial_d , Coefficient_type>{ + : public CGAL::cpp98::unary_function< Polynomial_d , Coefficient_type>{ Coefficient_type operator()(const Polynomial_d& p) const { return p.content(); } @@ -287,11 +287,11 @@ public: typedef ICoeff Innermost_coefficient_type; struct Degree - : public CGAL::unary_function< ICoeff , int > { + : public CGAL::cpp98::unary_function< ICoeff , int > { int operator()(const ICoeff&) const { return 0; } }; struct Total_degree - : public CGAL::unary_function< ICoeff , int > { + : public CGAL::cpp98::unary_function< ICoeff , int > { int operator()(const ICoeff&) const { return 0; } }; @@ -309,14 +309,14 @@ public: typedef Null_functor Differentiate; struct Is_square_free - : public CGAL::unary_function< ICoeff, bool > { + : public CGAL::cpp98::unary_function< ICoeff, bool > { bool operator()( const ICoeff& ) const { return true; } }; struct Make_square_free - : public CGAL::unary_function< ICoeff, ICoeff>{ + : public CGAL::cpp98::unary_function< ICoeff, ICoeff>{ ICoeff operator()( const ICoeff& x ) const { if (CGAL::is_zero(x)) return x ; else return ICoeff(1); @@ -329,7 +329,7 @@ public: typedef Null_functor Pseudo_division_quotient; struct Gcd_up_to_constant_factor - : public CGAL::binary_function< ICoeff, ICoeff, ICoeff >{ + : public CGAL::cpp98::binary_function< ICoeff, ICoeff, ICoeff >{ ICoeff operator()(const ICoeff& x, const ICoeff& y) const { if (CGAL::is_zero(x) && CGAL::is_zero(y)) return ICoeff(0); @@ -341,7 +341,7 @@ public: typedef Null_functor Integral_division_up_to_constant_factor; struct Univariate_content_up_to_constant_factor - : public CGAL::unary_function< ICoeff, ICoeff >{ + : public CGAL::cpp98::unary_function< ICoeff, ICoeff >{ ICoeff operator()(const ICoeff& ) const { // TODO: Why not return 0 if argument is 0 ? return ICoeff(1); @@ -354,7 +354,7 @@ public: typedef Null_functor Evaluate_homogeneous; struct Innermost_leading_coefficient - :public CGAL::unary_function { + :public CGAL::cpp98::unary_function { const ICoeff& operator()(const ICoeff& x){return x;} }; @@ -368,7 +368,7 @@ public: }; struct Get_innermost_coefficient - : public CGAL::binary_function< ICoeff, Polynomial_d, Exponent_vector > { + : public CGAL::cpp98::binary_function< ICoeff, Polynomial_d, Exponent_vector > { const ICoeff& operator()( const Polynomial_d& p, Exponent_vector ) { return p; } @@ -475,7 +475,7 @@ private: // coeff type has no comparison operators available. private: struct Compare_exponents_coeff_pair - : public CGAL::binary_function< + : public CGAL::cpp98::binary_function< std::pair< Exponent_vector, Innermost_coefficient_type >, std::pair< Exponent_vector, Innermost_coefficient_type >, bool > @@ -701,7 +701,7 @@ public: // Get_coefficient; struct Get_coefficient - : public CGAL::binary_function { + : public CGAL::cpp98::binary_function { const Coefficient_type& operator()( const Polynomial_d& p, int i) const { CGAL_STATIC_THREAD_LOCAL_VARIABLE(Coefficient_type, zero, 0); @@ -715,8 +715,9 @@ public: // Get_innermost_coefficient; struct Get_innermost_coefficient - : public - CGAL::binary_function< Polynomial_d, Exponent_vector, Innermost_coefficient_type > + : public CGAL::cpp98::binary_function< Polynomial_d, + Exponent_vector, + Innermost_coefficient_type > { const Innermost_coefficient_type& @@ -729,7 +730,9 @@ public: return gic( gc( p, exponent ), ev ); }; }; - + + typedef CGAL::internal::Monomial_representation Monomial_representation; + // Swap variable x_i with x_j struct Swap { typedef Polynomial_d result_type; @@ -834,7 +837,7 @@ public: typedef CGAL::internal::Degree Degree; // Total_degree; - struct Total_degree : public CGAL::unary_function< Polynomial_d , int >{ + struct Total_degree : public CGAL::cpp98::unary_function< Polynomial_d , int >{ int operator()(const Polynomial_d& p) const { typedef Polynomial_traits_d COEFF_POLY_TRAITS; typename COEFF_POLY_TRAITS::Total_degree total_degree; @@ -852,7 +855,7 @@ public: // Leading_coefficient; struct Leading_coefficient - : public CGAL::unary_function< Polynomial_d , Coefficient_type>{ + : public CGAL::cpp98::unary_function< Polynomial_d , Coefficient_type>{ const Coefficient_type& operator()(const Polynomial_d& p) const { return p.lcoeff(); } @@ -860,7 +863,7 @@ public: // Innermost_leading_coefficient; struct Innermost_leading_coefficient - : public CGAL::unary_function< Polynomial_d , Innermost_coefficient_type>{ + : public CGAL::cpp98::unary_function< Polynomial_d , Innermost_coefficient_type>{ const Innermost_coefficient_type& operator()(const Polynomial_d& p) const { typename PTC::Innermost_leading_coefficient ilcoeff; @@ -872,7 +875,7 @@ public: //return a canonical representative of all constant multiples. struct Canonicalize - : public CGAL::unary_function{ + : public CGAL::cpp98::unary_function{ private: inline Polynomial_d canonicalize_(Polynomial_d p, CGAL::Tag_true) const @@ -914,7 +917,7 @@ public: // Differentiate; struct Differentiate - : public CGAL::unary_function{ + : public CGAL::cpp98::unary_function{ Polynomial_d operator()(Polynomial_d p, int i = (d-1)) const { if (i == (d-1) ){ @@ -931,7 +934,7 @@ public: // Evaluate; struct Evaluate - :public CGAL::binary_function{ + :public CGAL::cpp98::binary_function{ // Evaluate with respect to one variable Coefficient_type operator()(const Polynomial_d& p, const Coefficient_type& x) const { @@ -1048,7 +1051,7 @@ public: struct Construct_coefficient_const_iterator_range - : public CGAL::unary_function< Polynomial_d, + : public CGAL::cpp98::unary_function< Polynomial_d, Coefficient_const_iterator_range> { Coefficient_const_iterator_range operator () (const Polynomial_d& p) const { @@ -1057,7 +1060,7 @@ struct Construct_coefficient_const_iterator_range }; struct Construct_innermost_coefficient_const_iterator_range - : public CGAL::unary_function< Polynomial_d, + : public CGAL::cpp98::unary_function< Polynomial_d, Innermost_coefficient_const_iterator_range> { Innermost_coefficient_const_iterator_range operator () (const Polynomial_d& p) const { @@ -1068,7 +1071,7 @@ struct Construct_innermost_coefficient_const_iterator_range }; struct Is_square_free - : public CGAL::unary_function< Polynomial_d, bool >{ + : public CGAL::cpp98::unary_function< Polynomial_d, bool >{ bool operator()( const Polynomial_d& p ) const { if( !internal::may_have_multiple_factor( p ) ) return true; @@ -1093,7 +1096,7 @@ struct Construct_innermost_coefficient_const_iterator_range struct Make_square_free - : public CGAL::unary_function< Polynomial_d, Polynomial_d >{ + : public CGAL::cpp98::unary_function< Polynomial_d, Polynomial_d >{ Polynomial_d operator()(const Polynomial_d& p) const { if (CGAL::is_zero(p)) return p; @@ -1128,7 +1131,7 @@ struct Construct_innermost_coefficient_const_iterator_range }; struct Pseudo_division_quotient - :public CGAL::binary_function { + :public CGAL::cpp98::binary_function { Polynomial_d operator()(const Polynomial_d& f, const Polynomial_d& g) const { @@ -1140,7 +1143,7 @@ struct Construct_innermost_coefficient_const_iterator_range }; struct Pseudo_division_remainder - :public CGAL::binary_function { + :public CGAL::cpp98::binary_function { Polynomial_d operator()(const Polynomial_d& f, const Polynomial_d& g) const { @@ -1152,7 +1155,7 @@ struct Construct_innermost_coefficient_const_iterator_range }; struct Gcd_up_to_constant_factor - :public CGAL::binary_function { + :public CGAL::cpp98::binary_function { Polynomial_d operator()(const Polynomial_d& p, const Polynomial_d& q) const { if(p==q) return CGAL::canonicalize(p); @@ -1169,7 +1172,7 @@ struct Construct_innermost_coefficient_const_iterator_range }; struct Integral_division_up_to_constant_factor - :public CGAL::binary_function { + :public CGAL::cpp98::binary_function { @@ -1198,7 +1201,7 @@ struct Construct_innermost_coefficient_const_iterator_range }; struct Univariate_content_up_to_constant_factor - :public CGAL::unary_function { + :public CGAL::cpp98::unary_function { Coefficient_type operator()(const Polynomial_d& p) const { typename PTC::Gcd_up_to_constant_factor gcd_utcf; @@ -1273,7 +1276,7 @@ struct Construct_innermost_coefficient_const_iterator_range }; struct Shift - : public CGAL::binary_function< Polynomial_d,int,Polynomial_d >{ + : public CGAL::cpp98::binary_function< Polynomial_d,int,Polynomial_d >{ Polynomial_d operator()(const Polynomial_d& p, int e, int i = (d-1)) const { @@ -1291,7 +1294,7 @@ struct Construct_innermost_coefficient_const_iterator_range }; struct Negate - : public CGAL::unary_function< Polynomial_d, Polynomial_d >{ + : public CGAL::cpp98::unary_function< Polynomial_d, Polynomial_d >{ Polynomial_d operator()(const Polynomial_d& p, int i = (d-1)) const { Construct_polynomial construct; @@ -1309,7 +1312,7 @@ struct Construct_innermost_coefficient_const_iterator_range }; struct Invert - : public CGAL::unary_function< Polynomial_d , Polynomial_d >{ + : public CGAL::cpp98::unary_function< Polynomial_d , Polynomial_d >{ Polynomial_d operator()(Polynomial_d p, int i = (PT::d-1)) const { if (i == (d-1)){ p.reversal(); @@ -1323,7 +1326,7 @@ struct Construct_innermost_coefficient_const_iterator_range }; struct Translate - : public CGAL::binary_function< Polynomial_d , Innermost_coefficient_type, + : public CGAL::cpp98::binary_function< Polynomial_d , Innermost_coefficient_type, Polynomial_d >{ Polynomial_d operator()( @@ -1366,10 +1369,11 @@ struct Construct_innermost_coefficient_const_iterator_range } }; - struct Scale - : public - CGAL::binary_function< Polynomial_d, Innermost_coefficient_type, Polynomial_d > { - + struct Scale + : public CGAL::cpp98::binary_function< Polynomial_d, + Innermost_coefficient_type, + Polynomial_d > + { Polynomial_d operator()( Polynomial_d p, const Innermost_coefficient_type& c, int i = (PT::d-1) ) const { CGAL_precondition( i <= d-1 ); @@ -1414,7 +1418,7 @@ struct Construct_innermost_coefficient_const_iterator_range }; struct Resultant - : public CGAL::binary_function{ + : public CGAL::cpp98::binary_function{ Coefficient_type operator()( @@ -1537,10 +1541,6 @@ struct Construct_innermost_coefficient_const_iterator_range }; - typedef - CGAL::internal::Monomial_representation - Monomial_representation; - // returns the Exponten_vector of the innermost leading coefficient struct Degree_vector{ typedef Exponent_vector result_type; diff --git a/Polytope_distance_d/include/CGAL/Polytope_distance_d.h b/Polytope_distance_d/include/CGAL/Polytope_distance_d.h index 0a1ab787fe5..909ffa09cf6 100644 --- a/Polytope_distance_d/include/CGAL/Polytope_distance_d.h +++ b/Polytope_distance_d/include/CGAL/Polytope_distance_d.h @@ -73,7 +73,7 @@ namespace PD_detail { // functor for a fixed column of A template - class A_column : public CGAL::unary_function + class A_column : public CGAL::cpp98::unary_function { public: typedef NT result_type; @@ -121,7 +121,7 @@ namespace PD_detail { // functor for matrix A template - class A_matrix : public CGAL::unary_function + class A_matrix : public CGAL::cpp98::unary_function , boost::counting_iterator > > @@ -177,7 +177,7 @@ namespace PD_detail { // 1 (row d+1) template - class B_vector : public CGAL::unary_function + class B_vector : public CGAL::cpp98::unary_function { public: typedef NT result_type; @@ -214,7 +214,7 @@ namespace PD_detail { // functor for a fixed row of D; note that we have to return 2D in // order to please the QP_solver template - class D_row : public CGAL::unary_function + class D_row : public CGAL::cpp98::unary_function { public: typedef NT result_type; @@ -256,7 +256,7 @@ namespace PD_detail { // functor for matrix D template - class D_matrix : public CGAL::unary_function + class D_matrix : public CGAL::cpp98::unary_function , boost::counting_iterator > > { diff --git a/Polytope_distance_d/include/CGAL/width_assertions.h b/Polytope_distance_d/include/CGAL/width_assertions.h index 011de69d956..5df80c2ce3e 100644 --- a/Polytope_distance_d/include/CGAL/width_assertions.h +++ b/Polytope_distance_d/include/CGAL/width_assertions.h @@ -95,7 +95,7 @@ #define VISITED_CHECK 0 #define IMPASSABLE_CHECK 0 - #include + #include #define DEBUGENDL(doit,msg,var)\ if(doit!=0) std::cout << msg << " " << var << endl; diff --git a/Principal_component_analysis/demo/Principal_component_analysis/CMakeLists.txt b/Principal_component_analysis/demo/Principal_component_analysis/CMakeLists.txt index 721a4e64f5f..c7f68b6629c 100644 --- a/Principal_component_analysis/demo/Principal_component_analysis/CMakeLists.txt +++ b/Principal_component_analysis/demo/Principal_component_analysis/CMakeLists.txt @@ -23,14 +23,7 @@ include( ${CGAL_USE_FILE} ) # Find Qt5 itself find_package(Qt5 QUIET COMPONENTS Xml Script OpenGL) -# Find QGLViewer -if(Qt5_FOUND) - find_package(QGLViewer ) -endif(Qt5_FOUND) - -if(CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND) - - include_directories ( ${QGLVIEWER_INCLUDE_DIR} ) +if(CGAL_Qt5_FOUND AND Qt5_FOUND ) qt5_wrap_ui( UI_FILES MainWindow.ui ) @@ -49,15 +42,14 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND) add_executable ( PCA_demo PCA_demo.cpp ${UI_FILES} ${CGAL_Qt5_RESOURCE_FILES} ${CGAL_Qt5_MOC_FILES}) target_link_libraries( PCA_demo PRIVATE - CGAL::CGAL CGAL::CGAL_Qt5 Qt5::Gui - ${QGLVIEWER_LIBRARIES} ) + CGAL::CGAL CGAL::CGAL_Qt5 Qt5::Gui) add_to_cached_list( CGAL_EXECUTABLE_TARGETS PCA_demo ) include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake) cgal_add_compilation_test(PCA_demo) -else (CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND) +else (CGAL_Qt5_FOUND AND Qt5_FOUND ) set(PCA_MISSING_DEPS "") @@ -69,10 +61,7 @@ else (CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND) set(PCA_MISSING_DEPS "Qt5, ${PCA_MISSING_DEPS}") endif() - if(NOT QGLVIEWER_FOUND) - set(PCA_MISSING_DEPS "QGLViewer, ${PCA_MISSING_DEPS}") - endif() - + message(STATUS "NOTICE: This demo requires ${PCA_MISSING_DEPS} and will not be compiled.") -endif (CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND) +endif (CGAL_Qt5_FOUND AND Qt5_FOUND ) diff --git a/Principal_component_analysis/demo/Principal_component_analysis/MainWindow.cpp b/Principal_component_analysis/demo/Principal_component_analysis/MainWindow.cpp index 656cca30262..1d9eaabc9d1 100644 --- a/Principal_component_analysis/demo/Principal_component_analysis/MainWindow.cpp +++ b/Principal_component_analysis/demo/Principal_component_analysis/MainWindow.cpp @@ -79,7 +79,7 @@ void MainWindow::updateViewerBBox() const double xmax = bbox.xmax(); const double ymax = bbox.ymax(); const double zmax = bbox.zmax(); - qglviewer::Vec + CGAL::qglviewer::Vec vec_min(xmin, ymin, zmin), vec_max(xmax, ymax, zmax); m_pViewer->setSceneBoundingBox(vec_min,vec_max); @@ -170,9 +170,7 @@ void MainWindow::setAddKeyFrameKeyboardModifiers(::Qt::KeyboardModifiers m) void MainWindow::on_actionSave_snapshot_triggered() { - QApplication::setOverrideCursor(Qt::WaitCursor); - m_pViewer->saveSnapshot(QString("snapshot.png")); - QApplication::restoreOverrideCursor(); + m_pViewer->saveSnapshot(); } void MainWindow::on_actionCopy_snapshot_triggered() { @@ -181,11 +179,7 @@ void MainWindow::on_actionCopy_snapshot_triggered() QClipboard *qb = QApplication::clipboard(); m_pViewer->makeCurrent(); m_pViewer->raise(); -#if QGLVIEWER_VERSION >= 0x020700 QImage snapshot = m_pViewer->grabFramebuffer(); -#else - QImage snapshot = m_pViewer->grabFrameBuffer(true); -#endif qb->setImage(snapshot); QApplication::restoreOverrideCursor(); } diff --git a/Principal_component_analysis/demo/Principal_component_analysis/Viewer.cpp b/Principal_component_analysis/demo/Principal_component_analysis/Viewer.cpp index 32f8dc004a1..c05c0b55bf2 100644 --- a/Principal_component_analysis/demo/Principal_component_analysis/Viewer.cpp +++ b/Principal_component_analysis/demo/Principal_component_analysis/Viewer.cpp @@ -2,7 +2,7 @@ #include "Scene.h" Viewer::Viewer(QWidget* parent) - : QGLViewer(parent), + : CGAL::QGLViewer(parent), m_pScene(NULL) { } @@ -14,7 +14,7 @@ void Viewer::setScene(Scene* pScene) void Viewer::draw() { - QGLViewer::draw(); + CGAL::QGLViewer::draw(); if(m_pScene != NULL) { glClearColor(1.0f,1.0f,1.0f,1.0f); @@ -24,7 +24,7 @@ void Viewer::draw() void Viewer::initializeGL() { - QGLViewer::initializeGL(); + CGAL::QGLViewer::initializeGL(); makeCurrent(); initializeOpenGLFunctions(); setBackgroundColor(::Qt::white); diff --git a/Principal_component_analysis/demo/Principal_component_analysis/Viewer.h b/Principal_component_analysis/demo/Principal_component_analysis/Viewer.h index 5a8ac8f2e39..54b48885650 100644 --- a/Principal_component_analysis/demo/Principal_component_analysis/Viewer.h +++ b/Principal_component_analysis/demo/Principal_component_analysis/Viewer.h @@ -1,22 +1,21 @@ #ifndef VIEWER_H #define VIEWER_H #include -#include +#include #include // forward declarations class QWidget; class Scene; -class Viewer : public QGLViewer, -public QOpenGLFunctions_2_1{ +class Viewer : public CGAL::QGLViewer{ Q_OBJECT public: Viewer(QWidget * parent); - // overload several QGLViewer virtual functions + // overload several CGAL::QGLViewer virtual functions void draw(); void initializeGL(); void setScene(Scene* pScene); diff --git a/Property_map/include/CGAL/property_map.h b/Property_map/include/CGAL/property_map.h index e8612db429c..f589496dcba 100644 --- a/Property_map/include/CGAL/property_map.h +++ b/Property_map/include/CGAL/property_map.h @@ -36,6 +36,9 @@ #include // defines std::pair +#include +#include + namespace CGAL { /// \cond SKIP_DOXYGEN @@ -82,6 +85,8 @@ class OR_property_map { PM2 pm2; public: + OR_property_map() {} // required by boost::connected_components + OR_property_map(PM1 pm1, PM2 pm2) : pm1(pm1),pm2(pm2) {} @@ -100,9 +105,15 @@ class OR_property_map { put(pm.pm1,k, v); put(pm.pm2,k, v); } - }; +template +OR_property_map +make_OR_property_map(const PM1& pm1, const PM2& pm2) +{ + return OR_property_map(pm1, pm2); +} + // A property map that uses the result of a property map as key. template struct Property_map_binder{ @@ -415,6 +426,9 @@ inline typename Pointer_property_map::type make_property_map(std::vector& v) { + if(v.empty()){ + return make_property_map(static_cast(NULL)); + } return make_property_map(&v[0]); } @@ -440,24 +454,33 @@ make_property_map(const std::vector& v) } /// \ingroup PkgProperty_map -/// Property map that only returns the default value type -/// \cgalModels `ReadablePropertyMap` -template -struct Default_property_map{ +/// Property map that returns a fixed value. +/// Note that this value is chosen when the map is constructed and cannot +/// be changed afterwards. Specifically, the free function `put()` does nothing. +/// +/// \cgalModels `ReadWritePropertyMap` +template +struct Constant_property_map +{ const ValueType default_value; - - typedef typename InputIterator::value_type key_type; - typedef boost::readable_property_map_tag category; - Default_property_map(const ValueType& default_value = ValueType()) : default_value (default_value) { } - - /// Free function to use a get the value from an iterator using Input_iterator_property_map. - inline friend ValueType - get (const Default_property_map&, const key_type&){ return ValueType(); } + typedef KeyType key_type; + typedef ValueType value_type; + typedef boost::read_write_property_map_tag category; + + Constant_property_map(const value_type& default_value = value_type()) : default_value (default_value) { } + + /// Free function that returns `pm.default_value`. + inline friend value_type + get (const Constant_property_map& pm, const key_type&){ return pm.default_value; } + + /// Free function that does nothing. + inline friend void + put (const Constant_property_map&, const key_type&, const value_type&) { } }; /// \ingroup PkgProperty_map -/// Read-write Property map turning a set (such a `std::set`, +/// Read-write property map turning a set (such a `std::set`, /// `boost::unordered_set`, `std::unordered_set`) into a property map /// associating a Boolean to the value type of the set. The function `get` will /// return `true` if the key is inside the set and `false` otherwise. The `put` @@ -503,6 +526,50 @@ make_boolean_property_map(Set& set_) return Boolean_property_map(set_); } +/// \ingroup PkgProperty_map +/// Read-write property map doing on-the-fly conversions between two default constructible \cgal %Cartesian kernels. +/// Its value type is `GeomObject` and its key type is the same as `Vpm`. +/// `GeomObject` must be a geometric object from a \cgal kernel. +/// `Vpm` is a model `of ReadWritePropertyMap` and its value type must be +/// a geometric object of the same type as `GeomObject` but possibly from +/// another kernel. +/// Conversions between the two geometric objects are done using `Cartesian_converter`. +/// \cgalModels `ReadWritePropertyMap` +template +struct Cartesian_converter_property_map +{ + typedef typename boost::property_traits::key_type key_type; + typedef GeomObject value_type; + typedef value_type reference; + typedef boost::read_write_property_map_tag category; + Vpm vpm; + + typedef typename Kernel_traits::type K2; + typedef typename Kernel_traits::value_type>::type K1; + + Cartesian_converter_property_map(Vpm vpm):vpm(vpm){} + + friend value_type get(const Cartesian_converter_property_map& pm, const key_type& k) + { + return + CGAL::Cartesian_converter()(get(pm.vpm, k)); + } + + friend void put(Cartesian_converter_property_map& pm, const key_type& k, const value_type& v) + { + put(pm.vpm, k, CGAL::Cartesian_converter()(v)); + } +}; + +/// \ingroup PkgProperty_map +/// returns `Cartesian_converter_property_map(vpm)` +template +Cartesian_converter_property_map +make_cartesian_converter_property_map(Vpm vpm) +{ + return Cartesian_converter_property_map(vpm); +} + } // namespace CGAL diff --git a/Property_map/test/Property_map/CMakeLists.txt b/Property_map/test/Property_map/CMakeLists.txt index 1e0da002349..cf2d22c7469 100644 --- a/Property_map/test/Property_map/CMakeLists.txt +++ b/Property_map/test/Property_map/CMakeLists.txt @@ -49,10 +49,14 @@ include_directories( BEFORE ../../include ) include( CGAL_CreateSingleSourceCGALProgram ) +create_single_source_cgal_program( "test_property_map.cpp" ) + create_single_source_cgal_program( "dynamic_property_map.cpp" ) create_single_source_cgal_program( "dynamic_properties_test.cpp" ) +create_single_source_cgal_program( "kernel_converter_properties_test.cpp" ) + if(OpenMesh_FOUND) target_link_libraries( dynamic_properties_test PRIVATE ${OPENMESH_LIBRARIES} ) endif() diff --git a/Property_map/test/Property_map/kernel_converter_properties_test.cpp b/Property_map/test/Property_map/kernel_converter_properties_test.cpp new file mode 100644 index 00000000000..586cdd49383 --- /dev/null +++ b/Property_map/test/Property_map/kernel_converter_properties_test.cpp @@ -0,0 +1,37 @@ + +#include +#include +#include +#include +#include +#include + +typedef CGAL::Simple_cartesian K1; +typedef CGAL::Simple_cartesian > K2; +typedef K1::Point_3 Point_3; + +template +void +test() +{ + Mesh m; + CGAL::make_triangle(Point_3(2,0,0),Point_3(1,0,0),Point_3(1,1,0),m); + + typedef typename boost::property_map::type VPMap; + VPMap vmap = get(CGAL::vertex_point, m); + + CGAL::Cartesian_converter_property_map kcmap =CGAL::make_cartesian_converter_property_map(vmap); + CGAL_assertion(get(kcmap, *vertices(m).begin()) == CGAL::Point_3(2,0,0)); + put(kcmap, *vertices(m).begin(), CGAL::Point_3(0,2,3)); + CGAL_assertion(get(kcmap, *vertices(m).begin()) == CGAL::Point_3(0,2,3)); + +} + +int main() +{ + + typedef CGAL::Surface_mesh SM; + test(); + return 0; +} + diff --git a/Property_map/test/Property_map/test_property_map.cpp b/Property_map/test/Property_map/test_property_map.cpp new file mode 100644 index 00000000000..04813cf8e20 --- /dev/null +++ b/Property_map/test/Property_map/test_property_map.cpp @@ -0,0 +1,10 @@ + +#include +#include + +int main() +{ + std::vector v; + CGAL::make_property_map(v); + return 0; +} diff --git a/QP_solver/include/CGAL/QP_models.h b/QP_solver/include/CGAL/QP_models.h index 3ac7545bef3..34cef93d0db 100644 --- a/QP_solver/include/CGAL/QP_models.h +++ b/QP_solver/include/CGAL/QP_models.h @@ -396,7 +396,7 @@ namespace QP_model_detail { // maps a container to its begin-iterator, as specified by HowToBegin template struct Begin - : public CGAL::unary_function< Container, Iterator > + : public CGAL::cpp98::unary_function< Container, Iterator > { typedef Iterator result_type; result_type operator () ( const Container& v) const diff --git a/QP_solver/include/CGAL/QP_solution.h b/QP_solver/include/CGAL/QP_solution.h index 18f28041604..eabdf9cfa74 100644 --- a/QP_solver/include/CGAL/QP_solution.h +++ b/QP_solver/include/CGAL/QP_solution.h @@ -775,7 +775,7 @@ namespace QP_solution_detail { // Value_by_index // -------------- template < typename ET> - class Value_by_index : public CGAL::unary_function< std::size_t, ET> + class Value_by_index : public CGAL::cpp98::unary_function< std::size_t, ET> { public: typedef QP_solver_base QP; @@ -797,7 +797,7 @@ namespace QP_solution_detail { // Unbounded_direction_by_index // ---------------------------- template < typename ET> - class Unbounded_direction_by_index : public CGAL::unary_function< std::size_t, ET> + class Unbounded_direction_by_index : public CGAL::cpp98::unary_function< std::size_t, ET> { public: typedef QP_solver_base QP; @@ -818,7 +818,7 @@ namespace QP_solution_detail { // Lambda_by_index // --------------- template < typename ET> - class Lambda_by_index : public CGAL::unary_function< std::size_t, ET> + class Lambda_by_index : public CGAL::cpp98::unary_function< std::size_t, ET> { public: typedef QP_solver_base QP; diff --git a/QP_solver/include/CGAL/QP_solver/functors.h b/QP_solver/include/CGAL/QP_solver/functors.h index 09c390d543b..e9cb5fbcabb 100644 --- a/QP_solver/include/CGAL/QP_solver/functors.h +++ b/QP_solver/include/CGAL/QP_solver/functors.h @@ -65,12 +65,12 @@ class Map_with_default; // QP_vector_accessor // ------------------- template < class VectorIt, bool check_lower, bool check_upper > -class QP_vector_accessor : public CGAL::unary_function< +class QP_vector_accessor : public CGAL::cpp98::unary_function< int, typename std::iterator_traits::value_type > { public: typedef typename - CGAL::unary_function< + CGAL::cpp98::unary_function< int, typename std::iterator_traits::value_type >::result_type result_type; @@ -179,12 +179,12 @@ private: // Value_by_basic_index // -------------------- template < class RndAccIt > -class Value_by_basic_index : public CGAL::unary_function< +class Value_by_basic_index : public CGAL::cpp98::unary_function< int, typename std::iterator_traits::value_type > { public: typedef typename - CGAL::unary_function< + CGAL::cpp98::unary_function< int, typename std::iterator_traits ::value_type >::result_type result_type; diff --git a/QP_solver/test/QP_solver/master_mps_to_derivatives.cpp b/QP_solver/test/QP_solver/master_mps_to_derivatives.cpp index 14124909a84..6bebf123b03 100644 --- a/QP_solver/test/QP_solver/master_mps_to_derivatives.cpp +++ b/QP_solver/test/QP_solver/master_mps_to_derivatives.cpp @@ -174,7 +174,7 @@ create_output_file(const char *filename, // Note: "Bernd3" and not template struct tuple_add : - public CGAL::unary_function&, NT> + public CGAL::cpp98::unary_function&, NT> { NT operator()(const boost::tuple& t) const { diff --git a/Ridges_3/examples/Ridges_3/PolyhedralSurf.h b/Ridges_3/examples/Ridges_3/PolyhedralSurf.h index 13f555e1cf8..44a36ea7fd5 100644 --- a/Ridges_3/examples/Ridges_3/PolyhedralSurf.h +++ b/Ridges_3/examples/Ridges_3/PolyhedralSurf.h @@ -3,9 +3,6 @@ #include #include -#include -#include -#include #include #include #include diff --git a/Ridges_3/test/Ridges_3/PolyhedralSurf.h b/Ridges_3/test/Ridges_3/PolyhedralSurf.h index 13f555e1cf8..44a36ea7fd5 100644 --- a/Ridges_3/test/Ridges_3/PolyhedralSurf.h +++ b/Ridges_3/test/Ridges_3/PolyhedralSurf.h @@ -3,9 +3,6 @@ #include #include -#include -#include -#include #include #include #include diff --git a/STL_Extension/doc/STL_Extension/CGAL/iterator.h b/STL_Extension/doc/STL_Extension/CGAL/iterator.h index 86dbb468b56..6291a81be44 100644 --- a/STL_Extension/doc/STL_Extension/CGAL/iterator.h +++ b/STL_Extension/doc/STL_Extension/CGAL/iterator.h @@ -644,7 +644,7 @@ Join_input_iterator_2(I1 i1,I2 i2,const Op& op=Op()); /*! \ingroup STLIterators -The class `Join_input_iterator_3` joins two iterators. The result is again an iterator (of the same +The class `Join_input_iterator_3` joins three iterators. The result is again an iterator (of the same iterator category type as the original iterator) that reads an object from the stream and applies a function object to that object. diff --git a/STL_Extension/include/CGAL/Compact_container.h b/STL_Extension/include/CGAL/Compact_container.h index 308458b5e7e..b4960af00c4 100644 --- a/STL_Extension/include/CGAL/Compact_container.h +++ b/STL_Extension/include/CGAL/Compact_container.h @@ -1314,7 +1314,7 @@ namespace std { template < class DSC, bool Const > struct hash > - : public CGAL::unary_function, std::size_t> { + : public CGAL::cpp98::unary_function, std::size_t> { std::size_t operator()(const CGAL::internal::CC_iterator& i) const { diff --git a/STL_Extension/include/CGAL/Concurrent_compact_container.h b/STL_Extension/include/CGAL/Concurrent_compact_container.h index e0ad2fb5333..353f1628b2e 100644 --- a/STL_Extension/include/CGAL/Concurrent_compact_container.h +++ b/STL_Extension/include/CGAL/Concurrent_compact_container.h @@ -1068,7 +1068,7 @@ namespace std { template < class CCC, bool Const > struct hash > - : public CGAL::unary_function, std::size_t> { + : public CGAL::cpp98::unary_function, std::size_t> { std::size_t operator()(const CGAL::CCC_internal::CCC_iterator& i) const { diff --git a/STL_Extension/include/CGAL/In_place_list.h b/STL_Extension/include/CGAL/In_place_list.h index c5fc2e42ecc..face144af5e 100644 --- a/STL_Extension/include/CGAL/In_place_list.h +++ b/STL_Extension/include/CGAL/In_place_list.h @@ -803,7 +803,7 @@ namespace std { template < class T, class Alloc > struct hash > - : public CGAL::unary_function, std::size_t> { + : public CGAL::cpp98::unary_function, std::size_t> { std::size_t operator()(const CGAL::internal::In_place_list_iterator& i) const { @@ -814,7 +814,7 @@ namespace std { template < class T, class Alloc > struct hash > - : public CGAL::unary_function, std::size_t> { + : public CGAL::cpp98::unary_function, std::size_t> { std::size_t operator()(const CGAL::internal::In_place_list_const_iterator& i) const { diff --git a/STL_Extension/include/CGAL/assertions_behaviour.h b/STL_Extension/include/CGAL/assertions_behaviour.h index cd082c3892f..be0941fba1d 100644 --- a/STL_Extension/include/CGAL/assertions_behaviour.h +++ b/STL_Extension/include/CGAL/assertions_behaviour.h @@ -28,6 +28,12 @@ #ifndef CGAL_ASSERTIONS_BEHAVIOUR_H #define CGAL_ASSERTIONS_BEHAVIOUR_H +// workaround against the definition of EXIT in +#ifdef EXIT +# undef EXIT +#endif + + namespace CGAL { enum Failure_behaviour { ABORT, EXIT, EXIT_WITH_SUCCESS, CONTINUE, diff --git a/STL_Extension/include/CGAL/exceptions.h b/STL_Extension/include/CGAL/exceptions.h index 2dcc47a63e1..b07c0c50267 100644 --- a/STL_Extension/include/CGAL/exceptions.h +++ b/STL_Extension/include/CGAL/exceptions.h @@ -26,7 +26,19 @@ #include #include #include + +// Address the warning C4003: not enough actual parameters for macro 'BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY' +// lexical_cast.hpp includes files from boost/preprocessor +// This concerns boost 1_67_0 +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable: 4003) +#endif #include +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + namespace CGAL { diff --git a/STL_Extension/include/CGAL/function_objects.h b/STL_Extension/include/CGAL/function_objects.h index 9d5a046c28d..1218df36c7e 100644 --- a/STL_Extension/include/CGAL/function_objects.h +++ b/STL_Extension/include/CGAL/function_objects.h @@ -358,8 +358,8 @@ class Creator_uniform_d { template < class Op1, class Op2 > class Unary_compose_1 - : public CGAL::unary_function< typename Op2::argument_type, - typename Op1::result_type > + : public CGAL::cpp98::unary_function< typename Op2::argument_type, + typename Op1::result_type > { protected: Op1 op1; @@ -382,8 +382,8 @@ compose1_1(const Op1& op1, const Op2& op2) template < class Op1, class Op2, class Op3 > class Binary_compose_1 - : public CGAL::unary_function< typename Op2::argument_type, - typename Op1::result_type > + : public CGAL::cpp98::unary_function< typename Op2::argument_type, + typename Op1::result_type > { protected: Op1 op1; @@ -408,9 +408,9 @@ compose2_1(const Op1& op1, const Op2& op2, const Op3& op3) template < class Op1, class Op2 > class Unary_compose_2 - : public CGAL::binary_function< typename Op2::first_argument_type, - typename Op2::second_argument_type, - typename Op1::result_type > + : public CGAL::cpp98::binary_function< typename Op2::first_argument_type, + typename Op2::second_argument_type, + typename Op1::result_type > { protected: Op1 op1; @@ -435,9 +435,9 @@ compose1_2(const Op1& op1, const Op2& op2) template < class Op1, class Op2, class Op3 > class Binary_compose_2 - : public CGAL::binary_function< typename Op2::argument_type, - typename Op3::argument_type, - typename Op1::result_type > + : public CGAL::cpp98::binary_function< typename Op2::argument_type, + typename Op3::argument_type, + typename Op1::result_type > { protected: Op1 op1; diff --git a/STL_Extension/include/CGAL/functional.h b/STL_Extension/include/CGAL/functional.h index 99406282644..1fb79867d40 100644 --- a/STL_Extension/include/CGAL/functional.h +++ b/STL_Extension/include/CGAL/functional.h @@ -23,29 +23,32 @@ // // Author(s) : Andreas Fabri -#ifndef CGAL_UNARY_FUNCTION_H -#define CGAL_UNARY_FUNCTION_H +#ifndef CGAL_FUNCTIONAL_H +#define CGAL_FUNCTIONAL_H namespace CGAL { +namespace cpp98 { + /// Replacement for `std::unary_function` that is deprecated since C++11, - /// and removed from C++17 + /// and removed from C++17. template < typename ArgumentType, typename ResultType> struct unary_function { typedef ArgumentType argument_type; typedef ResultType result_type; }; - /// Replacement for `std::binary_function` that is deprecated since C++11, - /// and removed from C++17 + /// and removed from C++17. template < typename Arg1, typename Arg2, typename Result> struct binary_function { typedef Arg1 first_argument_type; typedef Arg2 second_argument_type; typedef Result result_type; }; - + +} // namespace cpp98 + } // namespace CGAL -#endif // CGAL_UNARY_FUNCTION_H +#endif // CGAL_FUNCTIONAL_H diff --git a/STL_Extension/include/CGAL/hash_openmesh.h b/STL_Extension/include/CGAL/hash_openmesh.h index 69aefdba401..e56f8f19d39 100644 --- a/STL_Extension/include/CGAL/hash_openmesh.h +++ b/STL_Extension/include/CGAL/hash_openmesh.h @@ -98,7 +98,7 @@ namespace std { template <> struct hash - : public CGAL::unary_function + : public CGAL::cpp98::unary_function { std::size_t operator()(const OpenMesh::BaseHandle& h) const @@ -109,7 +109,7 @@ struct hash template <> struct hash - : public CGAL::unary_function + : public CGAL::cpp98::unary_function { std::size_t operator()(const OpenMesh::VertexHandle& h) const @@ -120,7 +120,7 @@ struct hash template <> struct hash - : public CGAL::unary_function + : public CGAL::cpp98::unary_function { std::size_t operator()(const OpenMesh::HalfedgeHandle& h) const @@ -131,7 +131,7 @@ struct hash template <> struct hash - : public CGAL::unary_function + : public CGAL::cpp98::unary_function { std::size_t operator()(const OpenMesh::EdgeHandle& h) const @@ -142,7 +142,7 @@ struct hash template <> struct hash > - : public CGAL::unary_function + : public CGAL::cpp98::unary_function { std::size_t operator()(const CGAL::internal::OMesh_edge& h) const @@ -153,7 +153,7 @@ struct hash > template <> struct hash - : public CGAL::unary_function + : public CGAL::cpp98::unary_function { std::size_t operator()(const OpenMesh::FaceHandle& h) const diff --git a/STL_Extension/include/CGAL/internal/boost/array_binary_tree.hpp b/STL_Extension/include/CGAL/internal/boost/array_binary_tree.hpp index ed646779099..d016db28b46 100644 --- a/STL_Extension/include/CGAL/internal/boost/array_binary_tree.hpp +++ b/STL_Extension/include/CGAL/internal/boost/array_binary_tree.hpp @@ -20,10 +20,12 @@ #ifndef CGAL_INTERNAL_ARRAY_BINARY_TREE_HPP #define CGAL_INTERNAL_ARRAY_BINARY_TREE_HPP -#include -#include +#include + #include +#include + namespace CGAL { namespace internal { namespace boost_ { @@ -52,13 +54,10 @@ public: struct children_type { struct iterator - : ::boost::iterator + : public CGAL::cpp98::iterator { // replace with iterator_adaptor implementation -JGS - inline iterator() : i(0), n(0) { } inline iterator(const iterator& x) : r(x.r), i(x.i), n(x.n), id(x.id) { } inline iterator& operator=(const iterator& x) { diff --git a/STL_Extension/include/CGAL/iterator.h b/STL_Extension/include/CGAL/iterator.h index b88ed0cfd28..c7207a10c8b 100644 --- a/STL_Extension/include/CGAL/iterator.h +++ b/STL_Extension/include/CGAL/iterator.h @@ -30,18 +30,19 @@ #include -#include #include -#include -#include -#include +#include +#include +#include #include +#include + #include #include #include -#include - +#include +#include namespace CGAL { @@ -87,6 +88,8 @@ Iterator_range > make_prevent_deref_range(const I& begin, const return Iterator_range >(make_prevent_deref(begin), make_prevent_deref(end)); } +namespace cpp98 { + template struct iterator @@ -103,7 +106,8 @@ struct iterator typedef Reference reference; }; - +} // end namespace cpp98 + // +----------------------------------------------------------------+ // | Emptyset_iterator // +----------------------------------------------------------------+ @@ -111,7 +115,7 @@ struct iterator // +----------------------------------------------------------------+ struct Emptyset_iterator - : public CGAL::iterator< std::output_iterator_tag, void, void, void, void > + : public CGAL::cpp98::iterator< std::output_iterator_tag, void, void, void, void > { template< class T > Emptyset_iterator& operator=(const T&) { return *this; } @@ -131,7 +135,7 @@ struct Emptyset_iterator template < class Container > class Insert_iterator - : public CGAL::iterator< std::output_iterator_tag, void, void, void, void > + : public CGAL::cpp98::iterator< std::output_iterator_tag, void, void, void, void > { protected: Container *container; @@ -172,8 +176,8 @@ inserter(Container &x) template < class T > class Oneset_iterator - : public CGAL::iterator< std::bidirectional_iterator_tag, - void, void, void, void > + : public CGAL::cpp98::iterator< std::bidirectional_iterator_tag, + void, void, void, void > { T* t; @@ -279,7 +283,7 @@ private: // Undocumented, because there is some hope to merge it into Counting_iterator class Counting_output_iterator - : public CGAL::iterator< std::output_iterator_tag, void, void, void, void > + : public CGAL::cpp98::iterator< std::output_iterator_tag, void, void, void, void > { std::size_t *c; public: @@ -656,20 +660,19 @@ bool operator!=(const Filter_iterator& it1, { return !(it1 == it2); } template -class Join_input_iterator_1 : public -CGAL::iterator::iterator_category, - typename Op::result_type, - typename std::iterator_traits::difference_type, - typename Op::result_type*, - typename Op::result_type&> -{ -public: - typedef Join_input_iterator_1 Self; - typedef typename Op::result_type value_type; - typedef typename std::iterator_traits::difference_type difference_type; - typedef value_type* pointer; - typedef value_type& reference; - +class Join_input_iterator_1 +{ + typedef Join_input_iterator_1 Self; + + typedef typename std::iterator_traits::value_type arg_type; + +public: + typedef typename std::iterator_traits::iterator_category iterator_category; + typedef typename cpp11::result_of::type value_type; + typedef typename std::iterator_traits::difference_type difference_type; + typedef value_type* pointer; + typedef value_type& reference; + protected: I1 i1; Op op; @@ -742,20 +745,20 @@ public: }; template -class Join_input_iterator_2 : public -CGAL::iterator::iterator_category, - typename Op::result_type, - typename std::iterator_traits::difference_type, - typename Op::result_type*, - typename Op::result_type&> -{ -public: - typedef Join_input_iterator_2 Self; - typedef typename Op::result_type value_type; - typedef typename std::iterator_traits::difference_type difference_type; - typedef value_type* pointer; - typedef value_type& reference; - +class Join_input_iterator_2 +{ + typedef Join_input_iterator_2 Self; + + typedef typename std::iterator_traits::value_type arg_type_1; + typedef typename std::iterator_traits::value_type arg_type_2; + +public: + typedef typename std::iterator_traits::iterator_category iterator_category; + typedef typename cpp11::result_of::type value_type; + typedef typename std::iterator_traits::difference_type difference_type; + typedef value_type* pointer; + typedef value_type& reference; + protected: I1 i1; I2 i2; @@ -835,19 +838,21 @@ public: }; template -class Join_input_iterator_3 : public -CGAL::iterator::iterator_category, - typename Op::result_type, - typename std::iterator_traits::difference_type, - typename Op::result_type*, - typename Op::result_type&> -{ -public: - typedef Join_input_iterator_3 Self; - typedef typename Op::result_type value_type; - typedef typename std::iterator_traits::difference_type difference_type; - typedef value_type* pointer; - typedef value_type& reference; +class Join_input_iterator_3 +{ + typedef Join_input_iterator_3 Self; + + typedef typename std::iterator_traits::value_type arg_type_1; + typedef typename std::iterator_traits::value_type arg_type_2; + typedef typename std::iterator_traits::value_type arg_type_3; + +public: + typedef typename std::iterator_traits::iterator_category iterator_category; + typedef typename cpp11::result_of::type + value_type; + typedef typename std::iterator_traits::difference_type difference_type; + typedef value_type* pointer; + typedef value_type& reference; protected: I1 i1; @@ -880,7 +885,7 @@ public: Join_input_iterator_3& operator=(const Join_input_iterator_3& it) { i1 = it.i1; - i2 = it.i1; + i2 = it.i2; i3 = it.i3; op = it.op; return *this; @@ -1214,7 +1219,7 @@ public: template class Filter_output_iterator - : public CGAL::iterator + : public CGAL::cpp98::iterator { protected: _Iterator iterator; diff --git a/STL_Extension/include/CGAL/result_of.h b/STL_Extension/include/CGAL/result_of.h index 59c8f02e7f4..5d9382d5c4d 100644 --- a/STL_Extension/include/CGAL/result_of.h +++ b/STL_Extension/include/CGAL/result_of.h @@ -27,9 +27,21 @@ #ifndef CGAL_RESULT_OF_H #define CGAL_RESULT_OF_H +#include #include +// Address the warning C4003: not enough actual parameters for macro 'BOOST_PP_SEQ_DETAIL_IS_NOT_EMPTY' +// result_of.hpp includes files from boost/preprocessor +// This concerns boost 1_65_1 +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable: 4003) +#endif #include +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + #include namespace CGAL{ diff --git a/STL_Extension/test/STL_Extension/CMakeLists.txt b/STL_Extension/test/STL_Extension/CMakeLists.txt index 5b5d39ddaeb..319ff1503fd 100644 --- a/STL_Extension/test/STL_Extension/CMakeLists.txt +++ b/STL_Extension/test/STL_Extension/CMakeLists.txt @@ -47,7 +47,7 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "test_type_traits.cpp" ) create_single_source_cgal_program( "test_Uncertain.cpp" ) create_single_source_cgal_program( "test_vector.cpp" ) - + create_single_source_cgal_program( "test_join_iterators.cpp" ) else() message(STATUS "This program requires the CGAL library, and will not be compiled.") diff --git a/STL_Extension/test/STL_Extension/test_N_tuple.cpp b/STL_Extension/test/STL_Extension/test_N_tuple.cpp index f8e2d02deb5..666de2eaefe 100644 --- a/STL_Extension/test/STL_Extension/test_N_tuple.cpp +++ b/STL_Extension/test/STL_Extension/test_N_tuple.cpp @@ -1,13 +1,13 @@ -#define CGAL_NO_DEPRECATION_WARNINGS 1 +#include #include #include #include #include #include + int main() { -#ifndef CGAL_NO_DEPRECATED_CODE CGAL::Twotuple d2, t2(0,1); CGAL::Threetuple d3, t3(0,1,2); CGAL::Fourtuple d4, t4(0,1,2,3); @@ -17,6 +17,6 @@ int main() CGAL_USE(d3); CGAL_USE(t3); CGAL_USE(d4); CGAL_USE(t4); CGAL_USE(d6); CGAL_USE(t6); -#endif + return 0; } diff --git a/STL_Extension/test/STL_Extension/test_join_iterators.cpp b/STL_Extension/test/STL_Extension/test_join_iterators.cpp new file mode 100644 index 00000000000..495c3c9898b --- /dev/null +++ b/STL_Extension/test/STL_Extension/test_join_iterators.cpp @@ -0,0 +1,182 @@ +#include + +#include +#include + +#include + +typedef CGAL::Exact_predicates_exact_constructions_kernel EPECK; +typedef EPECK::Point_2 Point_2; +typedef EPECK::Compute_x_2 Compute_x_2; +typedef EPECK::Construct_midpoint_2 Construct_midpoint_2; +typedef EPECK::Collinear_2 Collinear_2; + +typedef std::vector Point_vector; +typedef Point_vector::iterator PV_it; +typedef Point_vector::const_iterator PV_cit; + +void test_join_input_iterator_1() +{ + Point_vector pv; + pv.push_back(Point_2(0.1, 0.1)); + + typedef CGAL::Join_input_iterator_1 Join; + + Join join; + Join join_bis(join); + join_bis = join; + + Join join_ter(pv.begin()); + Join join_quater(pv.begin(), Compute_x_2()); + assert(join_ter == join_quater); + + assert(join_ter.current_iterator1() == pv.begin()); + assert(*join_ter == 0.1); // calls Compute_x_2 + assert(join_ter[0] == 0.1); // calls Compute_x_2 + + Join join_quinquies(pv.end(), Compute_x_2()); + assert(join_ter != join_quinquies); + assert(join_ter < join_quinquies); + + ++join_ter; + assert(join_ter == join_quinquies); + --join_ter; + assert(join_ter.current_iterator1() == pv.begin()); + + assert((join_ter++).current_iterator1() == pv.begin()); + assert(join_ter == join_quinquies); + assert((join_ter--).current_iterator1() == pv.end()); + assert(join_ter.current_iterator1() == pv.begin()); + + join_ter += 1; + assert(join_ter == join_quinquies); + join_ter -= 1; + assert(join_ter.current_iterator1() == pv.begin()); + + join_ter = join_ter + 1; + assert(join_ter == join_quinquies); + join_ter = join_ter - 1; + assert(join_ter.current_iterator1() == pv.begin()); +} + +void test_join_input_iterator_2() +{ + Point_vector pv; + pv.push_back(Point_2(-1, -1)); + pv.push_back(Point_2(1, 1)); + + typedef CGAL::Join_input_iterator_2 Join; + + PV_cit first = pv.begin(), second = ++(pv.begin()); + + Join join; + Join join_bis(join); + join_bis = join; + + Join join_ter(first, second); + Join join_quater(first, second, Construct_midpoint_2()); + assert(join_ter == join_quater); + + assert(join_ter.current_iterator1() == first); + assert(join_ter.current_iterator2() == second); + assert(*join_ter == CGAL::ORIGIN); // calls Construct_midpoint_2 + assert(join_ter[0] == CGAL::ORIGIN); // calls Construct_midpoint_2 + + Join join_quinquies(second, pv.end(), Construct_midpoint_2()); + assert(join_ter != join_quinquies); + assert(join_ter < join_quinquies); + + ++join_ter; + assert(join_ter == join_quinquies); + --join_ter; + assert(join_ter.current_iterator1() == first); + assert(join_ter.current_iterator2() == second); + + assert((join_ter++).current_iterator1() == first); + assert(join_ter == join_quinquies); + assert((join_ter--).current_iterator1() == second); + assert(join_ter.current_iterator1() == first); + assert(join_ter.current_iterator2() == second); + + join_ter += 1; + assert(join_ter == join_quinquies); + join_ter -= 1; + assert(join_ter.current_iterator1() == first); + assert(join_ter.current_iterator2() == second); + + join_ter = join_ter + 1; + assert(join_ter == join_quinquies); + join_ter = join_ter - 1; + assert(join_ter.current_iterator1() == first); + assert(join_ter.current_iterator2() == second); +} + +void test_join_input_iterator_3() +{ + Point_vector pv; + pv.push_back(Point_2(-0.1, -0.1)); + pv.push_back(Point_2(CGAL::ORIGIN)); + pv.push_back(Point_2(0.1, 0.1)); + pv.push_back(Point_2(0.1, 0)); + + typedef CGAL::Join_input_iterator_3 Join; + + PV_cit first = pv.begin(), second = ++(pv.begin()), + third = ++(++(pv.begin())), fourth = --(pv.end()); + + Join join; + Join join_bis(join); + join_bis = join; + + Join join_ter(first, second, third); + Join join_quater(first, second, third, Collinear_2()); + assert(join_ter == join_quater); + + assert(join_ter.current_iterator1() == first); + assert(join_ter.current_iterator2() == second); + assert(join_ter.current_iterator3() == third); + assert(*join_ter); // calls Collinear_2 + assert(join_ter[0]); // calls Collinear_2 + assert(!(join_ter[1])); // calls Collinear_2 + + const Join join_quinquies(second, third, fourth, Collinear_2()); + assert(join_ter != join_quinquies); + assert(join_ter < join_quinquies); + + ++join_ter; + assert(join_ter == join_quinquies); + --join_ter; + assert(join_ter.current_iterator1() == first); + assert(join_ter.current_iterator2() == second); + assert(join_ter.current_iterator3() == third); + + assert((join_ter++).current_iterator1() == first); + assert(join_ter == join_quinquies); + assert((join_ter--).current_iterator1() == second); + assert(join_ter.current_iterator1() == first); + assert(join_ter.current_iterator2() == second); + assert(join_ter.current_iterator3() == third); + + join_ter += 1; + assert(join_ter == join_quinquies); + join_ter -= 1; + assert(join_ter.current_iterator1() == first); + assert(join_ter.current_iterator2() == second); + assert(join_ter.current_iterator3() == third); + + join_ter = join_ter + 1; + assert(join_ter == join_quinquies); + join_ter = join_ter - 1; + assert(join_ter.current_iterator1() == first); + assert(join_ter.current_iterator2() == second); + assert(join_ter.current_iterator3() == third); +} + +int main() +{ + test_join_input_iterator_1(); + test_join_input_iterator_2(); + test_join_input_iterator_3(); + + return EXIT_SUCCESS; +} diff --git a/STL_Extension/test/STL_Extension/test_namespaces.cpp b/STL_Extension/test/STL_Extension/test_namespaces.cpp index a313d5fdf08..cad548729ef 100644 --- a/STL_Extension/test/STL_Extension/test_namespaces.cpp +++ b/STL_Extension/test/STL_Extension/test_namespaces.cpp @@ -1,4 +1,5 @@ -#define CGAL_NO_DEPRECATION_WARNINGS 1 // because CGAL::copy_n is deprecated +#include // because CGAL::copy_n is deprecated + #include #if defined(BOOST_MSVC) @@ -21,10 +22,8 @@ int main() CGAL_USE(tuple); CGAL_USE(tuple2); -#ifndef CGAL_NO_DEPRECATED_CODE CGAL::copy_n(arr.begin(), 3, arr2.begin()); -#endif // not CGAL_NO_DEPRECATED_CODE - + CGAL::cpp0x::copy_n(arr.begin(), 3, arr2.begin()); CGAL::cpp11::copy_n(arr.begin(), 3, arr2.begin()); diff --git a/Scale_space_reconstruction_3/include/CGAL/Scale_space_reconstruction_3/internal/Auto_count.h b/Scale_space_reconstruction_3/include/CGAL/Scale_space_reconstruction_3/internal/Auto_count.h index dc046e34063..7dde1992d07 100644 --- a/Scale_space_reconstruction_3/include/CGAL/Scale_space_reconstruction_3/internal/Auto_count.h +++ b/Scale_space_reconstruction_3/include/CGAL/Scale_space_reconstruction_3/internal/Auto_count.h @@ -43,7 +43,7 @@ namespace internal { */ template < class T, class C = unsigned int > class Auto_count -: public CGAL::unary_function< const T&, std::pair< T, C > > { +: public CGAL::cpp98::unary_function< const T&, std::pair< T, C > > { mutable C i; // Note, not thread-safe. public: /// \name Constructors diff --git a/Scripts/developer_scripts/cgal_check_dependencies.sh b/Scripts/developer_scripts/cgal_check_dependencies.sh index de3f26f48b7..65b989a8ca2 100644 --- a/Scripts/developer_scripts/cgal_check_dependencies.sh +++ b/Scripts/developer_scripts/cgal_check_dependencies.sh @@ -1,6 +1,6 @@ #This script must be called from the CGAL root. set -e -set -x +[ -n "$CGAL_DEBUG_TRAVIS" ] && set -x while test $# -gt 0 do case "$1" in @@ -10,6 +10,8 @@ do echo "0 otherwise." exit 0 ;; + --check_headers) DO_CHECK_HEADERS="True" + ;; --*) echo "bad option $1" ;; *) DOX_PATH="$1" @@ -28,19 +30,23 @@ do fi done -cmake -DCGAL_ENABLE_CHECK_HEADERS=TRUE -DDOXYGEN_EXECUTABLE="$DOX_PATH" -DCGAL_COPY_DEPENDENCIES=TRUE -DCMAKE_CXX_FLAGS="-std=c++11" .. -make -j$(nproc --all) packages_dependencies +cmake -DCGAL_HEADER_ONLY=FALSE -DCGAL_ENABLE_CHECK_HEADERS=TRUE -DDOXYGEN_EXECUTABLE="$DOX_PATH" -DCGAL_COPY_DEPENDENCIES=TRUE -DCMAKE_CXX_FLAGS="-std=c++11" .. +if [ -n "$DO_CHECK_HEADERS" ]; then + make -j$(nproc --all) -k check_headers +fi +make -j$(nproc --all) -k packages_dependencies echo " Checks finished" for pkg_path in $CGAL_ROOT/* do pkg=$(basename $pkg_path) if [ -f "$pkg_path/package_info/$pkg/dependencies" ]; then - PKG_DIFF=$(diff -N -w "$pkg_path/package_info/$pkg/dependencies.old" "$pkg_path/package_info/$pkg/dependencies" || true) + PKG_DIFF=$(grep -Fxv -f "$pkg_path/package_info/$pkg/dependencies.old" "$pkg_path/package_info/$pkg/dependencies" || true) if [ -n "$PKG_DIFF" ]; then - HAS_DIFF=TRUE - echo "Differences in $pkg: $PKG_DIFF" - else - echo "No differencies in $pkg dependencies." + TOTAL_RES="Differences in $pkg: $PKG_DIFF are new and not committed.\n $TOTAL_RES" + fi + PKG_DIFF=$(grep -Fxv -f "$pkg_path/package_info/$pkg/dependencies" "$pkg_path/package_info/$pkg/dependencies.old" || true) + if [ -n "$PKG_DIFF" ]; then + TOTAL_RES="Differences in $pkg: $PKG_DIFF have disappeared.\n $TOTAL_RES" fi if [ -f $pkg_path/package_info/$pkg/dependencies.old ]; then rm $pkg_path/package_info/$pkg/dependencies.old @@ -50,8 +56,10 @@ done echo " Checks finished" cd $CGAL_ROOT rm -r dep_check_build -if [ -n "$HAS_DIFF" ]; then - echo " You should run cmake with options CGAL_ENABLE_CHECK_HEADERS and CGAL_COPY_DEPENDENCIES ON, make the target packages_dependencies and commit the new dependencies files." +if [ -n "$TOTAL_RES" ]; then + printf "$TOTAL_RES" + echo " You can run cmake with options CGAL_ENABLE_CHECK_HEADERS and CGAL_COPY_DEPENDENCIES ON, make the target packages_dependencies and commit the new dependencies files," + echo " or simply manually edit the problematic files." exit 1 else echo "The dependencies are up to date." diff --git a/SearchStructures/include/CGAL/Segment_tree_d.h b/SearchStructures/include/CGAL/Segment_tree_d.h index 1c0b6dafe39..625050bd1c5 100644 --- a/SearchStructures/include/CGAL/Segment_tree_d.h +++ b/SearchStructures/include/CGAL/Segment_tree_d.h @@ -107,7 +107,8 @@ protected: typedef Segment_tree_node Segment_tree_node_t; typedef Segment_tree_node *link_type; - std::allocator alloc; + typedef std::allocator allocator_type; + allocator_type alloc; C_Interface m_interface; bool is_built; @@ -197,7 +198,11 @@ protected: { Segment_tree_node_t node(l,r,kl,kr); Segment_tree_node_t* node_ptr = alloc.allocate(1); +#ifdef CGAL_CXX11 + std::allocator_traits::construct(alloc, node_ptr, node); +#else alloc.construct(node_ptr, node); +#endif return node_ptr; } @@ -205,7 +210,11 @@ protected: { Segment_tree_node_t node(kl,kr); Segment_tree_node_t* node_ptr = alloc.allocate(1); +#ifdef CGAL_CXX11 + std::allocator_traits::construct(alloc, node_ptr, node); +#else alloc.construct(node_ptr, node); +#endif return node_ptr; } @@ -213,7 +222,11 @@ protected: { Segment_tree_node_t node; Segment_tree_node_t* node_ptr = alloc.allocate(1); +#ifdef CGAL_CXX11 + std::allocator_traits::construct(alloc, node_ptr, node); +#else alloc.construct(node_ptr, node); +#endif return node_ptr; } @@ -298,7 +311,11 @@ protected: void delete_node(Segment_tree_node_t* node_ptr) { +#ifdef CGAL_CXX11 + std::allocator_traits::destroy(alloc, node_ptr); +#else alloc.destroy(node_ptr); +#endif alloc.deallocate(node_ptr,1); } diff --git a/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_2/Sqrt_extension_2.h b/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_2/Sqrt_extension_2.h index e461dfadefd..0560ebfc987 100644 --- a/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_2/Sqrt_extension_2.h +++ b/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_2/Sqrt_extension_2.h @@ -264,7 +264,7 @@ public: typedef Sqrt_extension_2 Real_embeddable; class Abs - : public CGAL::unary_function< Real_embeddable, Real_embeddable >{ + : public CGAL::cpp98::unary_function< Real_embeddable, Real_embeddable >{ public: Real_embeddable operator()(const Real_embeddable& x) const { return (x>=0)?x:-x; @@ -272,7 +272,7 @@ public: }; class Sgn - : public CGAL::unary_function< Real_embeddable, CGAL::Sign >{ + : public CGAL::cpp98::unary_function< Real_embeddable, CGAL::Sign >{ public: CGAL::Sign operator()(const Real_embeddable& x) const { return x.sign(); @@ -280,9 +280,10 @@ public: }; class Compare - : public CGAL::binary_function< Real_embeddable, - Real_embeddable, - CGAL::Comparison_result >{ + : public CGAL::cpp98::binary_function< Real_embeddable, + Real_embeddable, + CGAL::Comparison_result > + { public: CGAL::Comparison_result operator()( const Real_embeddable& x, @@ -294,7 +295,7 @@ public: }; class To_double - : public CGAL::unary_function< Real_embeddable, double >{ + : public CGAL::cpp98::unary_function< Real_embeddable, double >{ public: double operator()(const Real_embeddable& x) const { return x.to_double(); @@ -302,7 +303,7 @@ public: }; class To_interval - : public CGAL::unary_function< Real_embeddable, std::pair< double, double > >{ + : public CGAL::cpp98::unary_function< Real_embeddable, std::pair< double, double > >{ public: std::pair operator()(const Real_embeddable& x) const { return x.to_interval(); diff --git a/Skin_surface_3/test/Skin_surface_3/degenerate_test.cpp b/Skin_surface_3/test/Skin_surface_3/degenerate_test.cpp index fbc6f377732..59638cf9178 100644 --- a/Skin_surface_3/test/Skin_surface_3/degenerate_test.cpp +++ b/Skin_surface_3/test/Skin_surface_3/degenerate_test.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include #include diff --git a/Skin_surface_3/test/Skin_surface_3/degenerate_test_exact.cpp b/Skin_surface_3/test/Skin_surface_3/degenerate_test_exact.cpp index 86590e8a36b..ca7fd696be9 100644 --- a/Skin_surface_3/test/Skin_surface_3/degenerate_test_exact.cpp +++ b/Skin_surface_3/test/Skin_surface_3/degenerate_test_exact.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #include #include diff --git a/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_iso_box.h b/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_iso_box.h index 2366cfa35ba..134640fea7f 100644 --- a/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_iso_box.h +++ b/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_iso_box.h @@ -3,23 +3,20 @@ namespace CGAL { /*! \ingroup RangeQueryItemClasses -The class `Fuzzy_iso_box` implements fuzzy `d`-dimensional iso boxes. A fuzzy iso -box with fuzziness value \f$ \epsilon\f$ has as inner and outer approximations +The class `Fuzzy_iso_box` implements fuzzy `d`-dimensional (closed) iso boxes. +A fuzzy iso box with fuzziness value \f$ \epsilon\f$ has as inner and outer approximations a box respectively eroded and dilated by a `d`-dim square with side length \f$ \epsilon\f$. - -\attention Points in the interior of the inner approximation are always reported and points -that are not in the closure of the outer approximation are never reported. Other -points may or may not be reported. Subsequently, points on the boundary of the -inner and outer approximations may or may not be reported. Specifically when \f$ \epsilon = 0\f$, -points on the boundary of the box may or may not be reported. +Points are returned depending on their location respective to the approximations, +as follows: +- points in the inner approximation (boundary included) are always returned. +- points in the outer approximation (boundary included) and not in the previous + category may or may not be returned. +- points that do not fit in the two previous categories are never returned. \tparam Traits must be a model of the concept `SearchTraits`, for example `CGAL::Search_traits_2 >`. \cgalModels `FuzzyQueryItem` - -\sa `FuzzyQueryItem` - */ template< typename Traits > class Fuzzy_iso_box { diff --git a/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_sphere.h b/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_sphere.h index db3aec07db3..e5340061349 100644 --- a/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_sphere.h +++ b/Spatial_searching/doc/Spatial_searching/CGAL/Fuzzy_sphere.h @@ -7,23 +7,20 @@ The class `Fuzzy_sphere` implements fuzzy `d`-dimensional spheres. A fuzzy sphere with radius \f$ r\f$ and fuzziness value \f$ \epsilon\f$ has as inner approximation a sphere with radius \f$ r-\epsilon\f$ and as outer approximation a sphere with radius \f$ r+\epsilon\f$. +Points are returned depending on their location respective to the approximations, +as follows: +- points in the inner approximation (boundary included) are always returned. +- points in the outer approximation (boundary included) and not in the previous + category may or may not be returned. +- points that do not fit in the two previous categories are never returned. -\attention The fuzziness of a `Fuzzy_sphere` is specified by a parameter \f$ \epsilon\f$ -denoting a maximal allowed distance to the boundary of a sphere. -If the distance to the boundary is greater than \f$ \epsilon\f$, points inside the -object are always reported and points outside the sphere are never reported. -Points whose distance to the boundary is less than or equal to \f$ \epsilon\f$ -may or may not be reported. Subsequently, points on the inner and outer spheres -may or may not be reported. Specifically when \f$ \epsilon = 0\f$, points -on the sphere of radius \f$ r\f$ may or may not be reported. +Note that if the fuzziness value is strictly greater than the radius, there is no +inner approximation. \tparam Traits must be a model of the concept `SearchTraits`, for example `CGAL::Cartesian_d`. \cgalModels `FuzzyQueryItem` - -\sa `FuzzyQueryItem` - */ template< typename Traits > class Fuzzy_sphere { diff --git a/Spatial_searching/doc/Spatial_searching/Spatial_searching.txt b/Spatial_searching/doc/Spatial_searching/Spatial_searching.txt index 40ca743f96f..24a45166d30 100644 --- a/Spatial_searching/doc/Spatial_searching/Spatial_searching.txt +++ b/Spatial_searching/doc/Spatial_searching/Spatial_searching.txt @@ -151,16 +151,21 @@ GeneralDistance, Splitter, SpatialTree>` Exact range searching and approximate range searching are supported using exact or fuzzy `d`-dimensional objects enclosing a region. The fuzziness of the query object is specified by a parameter -\f$ \epsilon\f$ used to define inner and outer approximations of the query object. -Points in the interior of the inner approximation are always reported and points -that are not in the closure of the outer approximation are never reported. Other -points may or may not be reported. For exact range searching, -the fuzziness parameter \f$ \epsilon\f$ is set to zero. +\f$ \epsilon\f$ used to define inner and outer +approximations of the object. For example, in the class `Fuzzy_sphere`, +the \f$ \epsilon\f$-inner and outer approximations of a sphere of radius \f$ r\f$ +are defined as the spheres of radius \f$ r-\epsilon\f$ and \f$ r+\epsilon\f$, respectively. +When using fuzzy items, queries are reported as follows: +- Points that are within the inner approximation are always reported. +- Points that are within the outer approximation but not within the inner approximation +might or might not be reported. +- Points thare not within the outer approximation are never reported. + +For exact range searching the fuzziness parameter \f$ \epsilon\f$ is set to zero. The class `Kd_tree` implements range searching in the method `search`, which is a template method with an output iterator and a model of the -concept `FuzzyQueryItem` as `Fuzzy_iso_box` -or `Fuzzy_sphere`. +concept `FuzzyQueryItem` such as `Fuzzy_iso_box` or `Fuzzy_sphere`. For range searching of large data sets, the user may set the parameter `bucket_size` used in building the `kd` tree to a large value (e.g. 100), because in general the query time will be less than using the default value. diff --git a/Spatial_searching/examples/Spatial_searching/iso_rectangle_2_query.cpp b/Spatial_searching/examples/Spatial_searching/iso_rectangle_2_query.cpp index e4f30d6acd0..4ef739e9819 100644 --- a/Spatial_searching/examples/Spatial_searching/iso_rectangle_2_query.cpp +++ b/Spatial_searching/examples/Spatial_searching/iso_rectangle_2_query.cpp @@ -47,8 +47,7 @@ main() { // using value 0.1 for fuzziness paramater Fuzzy_iso_box approximate_range(p, q, 0.1); tree.search(std::back_inserter( result ), approximate_range); - std::cout << "The points in the fuzzy box [[0.1, 0.3], [0.6, 0.9]]^2 are: " - << std::endl; + std::cout << "The points in the fuzzy box [[0.1, 0.3], [0.6, 0.9]]^2 are: " << std::endl; std::copy (result.begin(), result.end(), std::ostream_iterator(std::cout,"\n") ); std::cout << std::endl; return 0; diff --git a/Spatial_searching/include/CGAL/Fuzzy_iso_box.h b/Spatial_searching/include/CGAL/Fuzzy_iso_box.h index b9f27e0992f..5fdb08c8fa3 100644 --- a/Spatial_searching/include/CGAL/Fuzzy_iso_box.h +++ b/Spatial_searching/include/CGAL/Fuzzy_iso_box.h @@ -97,59 +97,61 @@ namespace CGAL { public: - // default constructor - Fuzzy_iso_box(const SearchTraits& traits_=SearchTraits()):traits(traits_) {} + // default constructor + Fuzzy_iso_box(const SearchTraits& traits_=SearchTraits()):traits(traits_) {} - // constructor - Fuzzy_iso_box(const Point_d& p, const Point_d& q, FT epsilon=FT(0),const SearchTraits& traits_=SearchTraits()) - : traits(traits_), eps(epsilon) - { - construct(p,q); - } + // constructor + Fuzzy_iso_box(const Point_d& p, const Point_d& q, FT epsilon=FT(0),const SearchTraits& traits_=SearchTraits()) + : traits(traits_), eps(epsilon) + { + CGAL_precondition(epsilon >= 0); + construct(p,q); + } - //additional constructor if SearchTraits = Search_traits_adapter - template - Fuzzy_iso_box(const Point& p,const Point&q,FT epsilon=FT(0),const SearchTraits& traits_=SearchTraits(), - typename boost::enable_if::type>::type* = 0) - : traits(traits_), eps(epsilon) - { - construct(p,q); - } + //additional constructor if SearchTraits = Search_traits_adapter + template + Fuzzy_iso_box(const Point& p,const Point&q,FT epsilon=FT(0),const SearchTraits& traits_=SearchTraits(), + typename boost::enable_if::type>::type* = 0) + : traits(traits_), eps(epsilon) + { + CGAL_precondition(epsilon >= 0); + construct(p,q); + } - bool contains(const Point_d& p) const { - Construct_cartesian_const_iterator_d construct_it=traits.construct_cartesian_const_iterator_d_object(); - Cartesian_const_iterator_d pit = construct_it(p); - Cartesian_const_iterator_d minit= min_begin, maxit = max_begin; - for (unsigned int i = 0; i < dim; ++i, ++pit, ++minit, ++maxit) { - if ( ((*pit) < (*minit)) || ((*pit) >= (*maxit)) ) return false; - } - return true; - } + bool contains(const Point_d& p) const { + Construct_cartesian_const_iterator_d construct_it=traits.construct_cartesian_const_iterator_d_object(); + Cartesian_const_iterator_d pit = construct_it(p); + Cartesian_const_iterator_d minit= min_begin, maxit = max_begin; + for (unsigned int i = 0; i < dim; ++i, ++pit, ++minit, ++maxit) { + if ( ((*pit) < (*minit)) || ((*pit) > (*maxit)) ) + return false; + } + return true; + } - bool inner_range_intersects(const Kd_tree_rectangle& rectangle) const { - Cartesian_const_iterator_d minit= min_begin, maxit = max_begin; - for (unsigned int i = 0; i < dim; ++i, ++minit, ++maxit) { - if ( ((*maxit)-eps < rectangle.min_coord(i)) - || ((*minit)+eps >= rectangle.max_coord(i)) ) return false; - } - return true; - } + bool inner_range_intersects(const Kd_tree_rectangle& rectangle) const { + // test whether the box eroded by 'eps' intersects 'rectangle' + Cartesian_const_iterator_d minit= min_begin, maxit = max_begin; + for (unsigned int i = 0; i < dim; ++i, ++minit, ++maxit) { + if ( ((*maxit)-eps < rectangle.min_coord(i)) + || ((*minit)+eps > rectangle.max_coord(i)) ) + return false; + } + return true; + } - bool outer_range_contains(const Kd_tree_rectangle& rectangle) const { - Cartesian_const_iterator_d minit= min_begin, maxit = max_begin; - for (unsigned int i = 0; i < dim; ++i, ++minit, ++maxit) { - if ( ((*maxit)+eps < rectangle.max_coord(i) ) - || ((*minit)-eps >= rectangle.min_coord(i)) ) return false; - } - return true; - } - - - - - - }; // class Fuzzy_iso_box + bool outer_range_contains(const Kd_tree_rectangle& rectangle) const { + // test whether the box dilated by 'eps' contains 'rectangle' + Cartesian_const_iterator_d minit= min_begin, maxit = max_begin; + for (unsigned int i = 0; i < dim; ++i, ++minit, ++maxit) { + if ( ((*maxit)+eps < rectangle.max_coord(i) ) + || ((*minit)-eps > rectangle.min_coord(i)) ) + return false; + } + return true; + } +}; // class Fuzzy_iso_box } // namespace CGAL #endif // FUZZY_ISO_BOX_H diff --git a/Spatial_searching/include/CGAL/Fuzzy_sphere.h b/Spatial_searching/include/CGAL/Fuzzy_sphere.h index a89af1c9b0d..5953ac767a6 100644 --- a/Spatial_searching/include/CGAL/Fuzzy_sphere.h +++ b/Spatial_searching/include/CGAL/Fuzzy_sphere.h @@ -25,6 +25,7 @@ #include +#include #include #include @@ -33,134 +34,131 @@ namespace CGAL { - namespace internal{ - - template - class Fuzzy_sphere_impl{ - SearchTraits traits; - public: +namespace internal{ - typedef typename SearchTraits::FT FT; - typedef typename SearchTraits::Dimension Dimension; - private: +template +class Fuzzy_sphere_impl +{ +public: + typedef typename SearchTraits::FT FT; + typedef typename SearchTraits::Dimension Dimension; - Point_d c; - FT r; - FT eps; +private: + SearchTraits traits; - public: + Point_d c; + FT sq_radius; + FT sq_inner_radius; + FT sq_outer_radius; +public: + // default constructor + Fuzzy_sphere_impl(const SearchTraits& traits_=SearchTraits()):traits(traits_) {} - // default constructor - Fuzzy_sphere_impl(const SearchTraits& traits_=SearchTraits()):traits(traits_) {} - - - // constructor - Fuzzy_sphere_impl(const Point_d& center, FT radius, FT epsilon=FT(0),const SearchTraits& traits_=SearchTraits()) : - traits(traits_),c(center), r(radius), eps(epsilon) - { // avoid problems if eps > r - if (eps>r) eps=r; - } - - bool contains(const typename SearchTraits::Point_d& p) const { - // test whether the distance between c and p is less than the radius - FT squared_radius = r*r; - FT distance=FT(0); - typename SearchTraits::Construct_cartesian_const_iterator_d construct_it= - traits.construct_cartesian_const_iterator_d_object(); - typename SearchTraits::Cartesian_const_iterator_d cit = construct_it(c), - pit = construct_it(p), - end = construct_it(c, 0); - for (; cit != end - && (distance < squared_radius); ++cit, ++pit) { - distance += - ((*cit)-(*pit))*((*cit)-(*pit)); - } - - return (distance < squared_radius); - } - - bool inner_range_intersects(const Kd_tree_rectangle& rectangle) const { - // test whether the interior of a sphere - // with radius (r-eps) intersects 'rectangle', i.e. - // if the minimal distance of c to 'rectangle' is less than r-eps - FT distance = FT(0); - FT squared_radius = (r-eps)*(r-eps); - typename SearchTraits::Construct_cartesian_const_iterator_d construct_it= - traits.construct_cartesian_const_iterator_d_object(); - typename SearchTraits::Cartesian_const_iterator_d cit = construct_it(c), - end = construct_it(c, 0); - for (int i = 0; cit != end && (distance < squared_radius); ++cit, ++i) { - if ((*cit) < rectangle.min_coord(i)) - distance += - (rectangle.min_coord(i)-(*cit))*(rectangle.min_coord(i)-(*cit)); - if ((*cit) > rectangle.max_coord(i)) - distance += - ((*cit)-rectangle.max_coord(i))*((*cit)-rectangle.max_coord(i)); - } - - return (distance < squared_radius); - } - - - bool outer_range_contains(const Kd_tree_rectangle& rectangle) const { - // test whether the interior of a sphere - // with radius (r+eps) is contained by 'rectangle', i.e. - // if the maximal distance of c to the boundary of 'rectangle' - // is less than r+eps - FT distance=FT(0); - FT squared_radius = (r+eps)*(r+eps); - typename SearchTraits::Construct_cartesian_const_iterator_d construct_it= - traits.construct_cartesian_const_iterator_d_object(); - typename SearchTraits::Cartesian_const_iterator_d cit = construct_it(c), - end = construct_it(c, 0); - for (int i = 0; cit != end && (distance < squared_radius) ; ++cit,++i) { - if ((*cit) <= (rectangle.min_coord(i)+rectangle.max_coord(i))/FT(2)) - distance += - (rectangle.max_coord(i)-(*cit))*(rectangle.max_coord(i)-(*cit)); - else - distance += ((*cit)-rectangle.min_coord(i))*((*cit)-rectangle.min_coord(i)); - } - - return (distance < squared_radius); - } - }; // class Fuzzy_sphere_impl + // constructor + Fuzzy_sphere_impl(const Point_d& center, FT r, FT eps=FT(0), + const SearchTraits& traits_ = SearchTraits()) + : traits(traits_), c(center), sq_radius(r*r) + { + CGAL_precondition(r >= 0); + CGAL_precondition(eps >= 0); + sq_inner_radius = (eps > r) ? FT(-1) : (r - eps) * (r - eps); + sq_outer_radius = (r + eps) * (r + eps); } - - template - class Fuzzy_sphere: + + bool contains(const typename SearchTraits::Point_d& p) const { + // test whether the distance between c and p is less than the radius + FT distance=FT(0); + typename SearchTraits::Construct_cartesian_const_iterator_d construct_it= + traits.construct_cartesian_const_iterator_d_object(); + typename SearchTraits::Cartesian_const_iterator_d cit = construct_it(c), + pit = construct_it(p), end = construct_it(c, 0); + for (; cit != end && (distance <= sq_radius); ++cit, ++pit) { + distance += CGAL::square((*cit)-(*pit)); + } + + return (distance <= sq_radius); + } + + bool inner_range_intersects(const Kd_tree_rectangle& rectangle) const { + // test whether the sphere with radius (r-eps) intersects 'rectangle', i.e. + // if the minimal distance of c to 'rectangle' is less than r-eps + FT distance = FT(0); + typename SearchTraits::Construct_cartesian_const_iterator_d construct_it= + traits.construct_cartesian_const_iterator_d_object(); + typename SearchTraits::Cartesian_const_iterator_d cit = construct_it(c), + end = construct_it(c, 0); + for (int i = 0; cit != end && (distance <= sq_inner_radius); ++cit, ++i) { + if ((*cit) < rectangle.min_coord(i)) + distance += CGAL::square(rectangle.min_coord(i)-(*cit)); + else if ((*cit) > rectangle.max_coord(i)) + distance += CGAL::square((*cit)-rectangle.max_coord(i)); + } + + return (distance <= sq_inner_radius); + } + + + bool outer_range_contains(const Kd_tree_rectangle& rectangle) const { + // test whether the sphere with radius (r+eps) contains 'rectangle', + // i.e. if the maximal distance of c to the boundary of 'rectangle' + // is less than r+eps + FT distance=FT(0); + typename SearchTraits::Construct_cartesian_const_iterator_d construct_it= + traits.construct_cartesian_const_iterator_d_object(); + typename SearchTraits::Cartesian_const_iterator_d cit = construct_it(c), + end = construct_it(c, 0); + for (int i = 0; cit != end && (distance <= sq_outer_radius) ; ++cit,++i) { + if ((*cit) <= (rectangle.min_coord(i)+rectangle.max_coord(i))/FT(2)) + distance += CGAL::square(rectangle.max_coord(i)-(*cit)); + else + distance += CGAL::square((*cit)-rectangle.min_coord(i)); + } + + return (distance <= sq_outer_radius); + } +}; // class Fuzzy_sphere_impl + +} + +template +class Fuzzy_sphere: public internal::Fuzzy_sphere_impl - { - typedef internal::Fuzzy_sphere_impl Base; - typedef typename Base::FT FT; - public: - // constructors - Fuzzy_sphere(const SearchTraits& traits_=SearchTraits()):Base(traits_){}; - Fuzzy_sphere(const typename SearchTraits::Point_d& center, FT radius, FT epsilon=FT(0),const SearchTraits& traits_=SearchTraits()) : - Base(center,radius,epsilon,traits_) {} - }; - - //specialization for Search_traits_adapter - template - class Fuzzy_sphere< Search_traits_adapter > : - public internal::Fuzzy_sphere_impl,typename Base_traits::Point_d> - { - typedef Search_traits_adapter SearchTraits; - typedef internal::Fuzzy_sphere_impl Base; - typedef typename Base_traits::FT FT; - public: - // constructors - Fuzzy_sphere(const SearchTraits& traits_=SearchTraits()):Base(traits_){}; - Fuzzy_sphere(const typename Base_traits::Point_d& center, FT radius, FT epsilon=FT(0),const SearchTraits& traits_=SearchTraits()) : - Base(center,radius,epsilon,traits_) {} - Fuzzy_sphere(const typename SearchTraits::Point_d& center, FT radius, FT epsilon=FT(0), - const SearchTraits& traits_=SearchTraits(), - typename boost::disable_if< - boost::is_same >::type* = 0) - : Base(get(traits_.point_property_map(),center),radius,epsilon,traits_) {} - }; - +{ + typedef internal::Fuzzy_sphere_impl Base; + typedef typename Base::FT FT; +public: + // constructors + Fuzzy_sphere(const SearchTraits& traits_=SearchTraits()):Base(traits_){} + Fuzzy_sphere(const typename SearchTraits::Point_d& center, FT radius, FT epsilon=FT(0),const SearchTraits& traits_=SearchTraits()) : + Base(center,radius,epsilon,traits_) {} +}; + +//specialization for Search_traits_adapter +template +class Fuzzy_sphere< Search_traits_adapter > + : public internal::Fuzzy_sphere_impl,typename Base_traits::Point_d> +{ + typedef Search_traits_adapter SearchTraits; + typedef internal::Fuzzy_sphere_impl Base; + typedef typename Base_traits::FT FT; +public: + // constructors + Fuzzy_sphere(const SearchTraits& traits_=SearchTraits()):Base(traits_){} + + // Constructor for any point type that is not `SearchTraits::Point_d` + template // boost::disable_if requires a template argument to work + Fuzzy_sphere(const Point& center, FT radius, FT epsilon=FT(0),const SearchTraits& traits_=SearchTraits(), + typename boost::disable_if< + boost::is_same >::type* = 0) + : Base(center,radius,epsilon,traits_) {} + + Fuzzy_sphere(const typename SearchTraits::Point_d& center, FT radius, FT epsilon=FT(0), + const SearchTraits& traits_=SearchTraits()) + : Base(get(traits_.point_property_map(),center),radius,epsilon,traits_) {} +}; + } // namespace CGAL #endif // FUZZY_SPHERE_H diff --git a/Spatial_searching/include/CGAL/Kd_tree_rectangle.h b/Spatial_searching/include/CGAL/Kd_tree_rectangle.h index 22503e16fbd..1eb6efad609 100644 --- a/Spatial_searching/include/CGAL/Kd_tree_rectangle.h +++ b/Spatial_searching/include/CGAL/Kd_tree_rectangle.h @@ -35,7 +35,7 @@ namespace CGAL { template - struct set_bounds_from_pointer : public CGAL::unary_function { + struct set_bounds_from_pointer : public CGAL::cpp98::unary_function { int dim; T *lower; T *upper; diff --git a/Spatial_searching/include/CGAL/Search_traits_adapter.h b/Spatial_searching/include/CGAL/Search_traits_adapter.h index f6d4eae7c6d..1fc87b33290 100644 --- a/Spatial_searching/include/CGAL/Search_traits_adapter.h +++ b/Spatial_searching/include/CGAL/Search_traits_adapter.h @@ -33,6 +33,7 @@ #include #include +#include namespace CGAL{ @@ -111,11 +112,23 @@ public: // This is needed because of an undocumented requirement of // Orthogonal_k_neighbor_search and Orthogonal_incremental_neighbor_search: // Traits::Construct_cartesian_const_iterator should be callable - // on the query point type - typename Base_traits::Cartesian_const_iterator_d operator()(const typename Base_traits::Point_d& p) const + // on the query point type. If the query point type is the same as + // Point_with_info, we disable it. + + template // boost::disable_if requires a template argument to work + typename Base_traits::Cartesian_const_iterator_d operator()(const Point& p, + typename boost::disable_if< + boost::is_same >::type* = 0 + ) const { return Base::operator() (p); } - typename Base_traits::Cartesian_const_iterator_d operator()(const typename Base_traits::Point_d& p, int) const + template // boost::disable_if requires a template argument to work + typename Base_traits::Cartesian_const_iterator_d operator()(const Point& p, int, + typename boost::disable_if< + boost::is_same >::type* = 0 + ) const { return Base::operator() (p,0); } }; diff --git a/Spatial_searching/test/Spatial_searching/Circular_query.cpp b/Spatial_searching/test/Spatial_searching/Circular_query.cpp index 4b6ca65a341..fc1f92f335a 100644 --- a/Spatial_searching/test/Spatial_searching/Circular_query.cpp +++ b/Spatial_searching/test/Spatial_searching/Circular_query.cpp @@ -1,108 +1,171 @@ -// file : test/Spatial_searching/Circular_query.C // test whether circular queries are computed correctly for random data // // 1) generate list of query points using report_all // 2) remove and check reported points from these list // 3) check if no remaining points should have been reported +#include "Point_with_info.h" + #include -#include + #include #include #include -#include -#include #include + +#include #include -#include "Point_with_info.h" +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +typedef CGAL::Cartesian K; +typedef K::FT FT; +typedef K::Point_2 Point; +typedef K::Vector_2 Vector; + +typedef CGAL::Random_points_in_square_2 Random_points_iterator; +typedef CGAL::Random_points_on_circle_2 Random_points_on_circle_iterator; +typedef CGAL::Counting_iterator N_Random_points_iterator; +typedef CGAL::Search_traits_2 Traits; -typedef CGAL::Cartesian K; -typedef K::Point_2 Point; -typedef CGAL::Random_points_in_square_2 Random_points_iterator; -typedef CGAL::Counting_iterator N_Random_points_iterator; -typedef CGAL::Search_traits_2 Traits; //for Point_with_info -typedef Point_with_info_helper::type Point_with_info; -typedef Point_property_map Ppmap; -typedef CGAL::Search_traits_adapter Traits_with_info; +typedef Point_with_info_helper::type Point_with_info; +typedef Point_property_map Ppmap; +typedef CGAL::Search_traits_adapter Traits_with_info; -template -void run(std::list all_points){ - typedef CGAL::Fuzzy_sphere Fuzzy_circle; - typedef CGAL::Kd_tree Tree; +template +void run_with_fuzziness(std::list all_points, // intentional copy + const Point& center, + const FT radius, + const FT fuzziness, + CGAL::Random& rnd) +{ + typedef CGAL::Fuzzy_sphere Fuzzy_circle; + + std::cout << "test with center: " << center << " radius: " << radius << " eps: " << fuzziness << "... "; + + const FT inner_radius = radius - fuzziness; + const FT sq_inner_radius = (inner_radius < FT(0)) ? FT(-1) : inner_radius * inner_radius; + const FT outer_radius = radius + fuzziness; + const FT sq_outer_radius = outer_radius * outer_radius; + + // add a bunch of points on the boundary of the inner approximation + // (in general all the constructed points won't be exactly on the boundary, + // but as long as some are, that's okay) + std::size_t N = all_points.size(); + Random_points_on_circle_iterator rpocit(inner_radius, rnd); + for(std::size_t i=0, max=N/10; i Tree; // Insert also the N points in the tree Tree tree( - boost::make_transform_iterator(all_points.begin(),Create_point_with_info()), - boost::make_transform_iterator(all_points.end(),Create_point_with_info()) + boost::make_transform_iterator(all_points.begin(), Create_point_with_info()), + boost::make_transform_iterator(all_points.end(), Create_point_with_info()) ); - // define exact circular range query (fuzziness=0) - Point center(0.25, 0.25); - Fuzzy_circle exact_range(typename Traits::Point_d(center), 0.25); + Fuzzy_circle default_range(typename SearchTraits::Point_d(center), radius); + std::list result; + tree.search(std::back_inserter(result), default_range); - std::list result; - tree.search(std::back_inserter( result ), exact_range); - - typedef std::vector V; + typedef std::vector V; V vec; vec.resize(result.size()); - typename V::iterator it = tree.search(vec.begin(), exact_range); + typename V::iterator it = tree.search(vec.begin(), default_range); + CGAL_USE(it); assert(it == vec.end()); - - tree.search(CGAL::Emptyset_iterator(), Fuzzy_circle(center, 0.25) ); //test compilation when Point != Traits::Point_d - - // test the results of the exact query - std::list copy_all_points(all_points); - for (typename std::list::iterator pt=result.begin(); (pt != result.end()); ++pt) { - // a point with distance d to the center may be reported if d <= r - assert(CGAL::squared_distance(center, get_point(*pt)) <= 0.0625); - copy_all_points.remove(get_point(*pt)); - } - - for (std::list::iterator pt=copy_all_points.begin(); (pt != copy_all_points.end()); ++pt) { - if(CGAL::squared_distance(center, *pt) < 0.0625){ - // all points with a distance d < r must be reported - std::cout << "we missed " << *pt << " with distance = " << CGAL::squared_distance(center,*pt) << std::endl; - } - assert(CGAL::squared_distance(center, *pt) >= 0.0625); - } - result.clear(); - // approximate range searching using value 0.125 for fuzziness parameter - Fuzzy_circle approximate_range(typename Traits::Point_d(center), 0.25, 0.125); - tree.search(std::back_inserter( result ), approximate_range); - // test the results of the approximate query - for (typename std::list::iterator pt=result.begin(); (pt != result.end()); ++pt) { - // a point with distance d to the center may be reported if d <= r + eps - assert(CGAL::squared_distance(center,get_point(*pt))<=0.140625); // (0.25 + 0.125)² + tree.search(CGAL::Emptyset_iterator(), Fuzzy_circle(center, radius) ); //test compilation when Point != Traits::Point_d + + // range searching + Fuzzy_circle approximate_range(typename SearchTraits::Point_d(center), radius, fuzziness); + tree.search(std::back_inserter(result), approximate_range); + std::cout << result.size() << " hits... Verifying correctness..."; + + // test the results + for(typename std::list::iterator pt=result.begin(); (pt != result.end()); ++pt) + { + // a point with distance d to the center can only be reported if d <= r + eps + bool is_correct = (CGAL::squared_distance(center, get_point(*pt)) <= sq_outer_radius); + if(!is_correct) + std::cout << get_point(*pt) << " at distance = " << CGAL::squared_distance(center, get_point(*pt)) + << " should not have been reported (max is: " << sq_outer_radius << ")" << std::endl; + assert(is_correct); all_points.remove(get_point(*pt)); } - for (std::list::iterator pt=all_points.begin(); (pt != all_points.end()); ++pt) { - // all points with a distance d < r - eps must be reported - if(CGAL::squared_distance(center, *pt) < 0.015625){ // (0.25 - 0.125)² - std::cout << "we missed " << *pt << " with distance = " << CGAL::squared_distance(center,*pt) << std::endl; + // note: if eps > r, the squared radius is set to '-1'. We cannot have missed + // any point because there is no inner approximation. + if(sq_inner_radius >= FT(0)) + { + for(std::list::const_iterator pt=all_points.begin(); (pt != all_points.end()); ++pt) + { + // all points with a distance d <= r - eps must have been reported + bool is_correct = (CGAL::squared_distance(center,*pt) > sq_inner_radius); + if(!is_correct) + std::cout << "missed " << *pt << " with distance = " << CGAL::squared_distance(center,*pt) << std::endl; + + assert(is_correct); } - assert(CGAL::squared_distance(center,*pt) >= 0.015625); } + std::cout << "done" << std::endl; } -int main() { +template +void run(std::list all_points, // intentional copy + CGAL::Random& rnd) +{ + Point center(0.25, 0.25); - const int N=1000; + // add some interesting points + all_points.push_back(center); + + run_with_fuzziness(all_points, center, 0. /*radius*/, 0. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, center, 0.25 /*radius*/, 0. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, center, 0.25 /*radius*/, 0.125 /*fuzziness*/, rnd); + run_with_fuzziness(all_points, center, 0.25 /*radius*/, 0.25 /*fuzziness*/, rnd); + run_with_fuzziness(all_points, center, 0.25 /*radius*/, 1. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, center, 1. /*radius*/, 0. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, center, 1. /*radius*/, 0.25 /*fuzziness*/, rnd); + run_with_fuzziness(all_points, center, 10. /*radius*/, 0. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, center, 10. /*radius*/, 10. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, center, 10. /*radius*/, 100. /*fuzziness*/, rnd); +} + +int main() +{ + CGAL::Set_ieee_double_precision pfr; + + CGAL::Random rnd = CGAL::get_default_random(); + std::cout << "seed: " << rnd.get_seed() << std::endl; // generator for random data points in the square ( (-1,-1), (1,1) ) - Random_points_iterator rpit(1.0); + Random_points_iterator rpit(1.0, rnd); // construct list containing N random points + const int N=1000; std::list all_points(N_Random_points_iterator(rpit,0), N_Random_points_iterator(N)); - run(all_points); - run(all_points); + run(all_points, rnd); + run(all_points, rnd); return 0; } diff --git a/Spatial_searching/test/Spatial_searching/Iso_rectangle_2_query.cpp b/Spatial_searching/test/Spatial_searching/Iso_rectangle_2_query.cpp index 15abb583eb1..a5afbefee39 100644 --- a/Spatial_searching/test/Spatial_searching/Iso_rectangle_2_query.cpp +++ b/Spatial_searching/test/Spatial_searching/Iso_rectangle_2_query.cpp @@ -1,101 +1,188 @@ -// file: Iso_rectangle_2_query.C +// test whether box queries are computed correctly for random data +// +// 1) generate list of query points using report_all +// 2) remove and check reported points from these list +// 3) check if no remaining points should have been reported #include -#include + +#include "Point_with_info.h" + #include #include #include -#include #include -#include -#include "Point_with_info.h" +#include +#include + +#include #include #include -typedef CGAL::Simple_cartesian K; -typedef K::Point_2 Point; -typedef K::Vector_2 Vector; -typedef K::Iso_rectangle_2 Iso_rectangle; -typedef CGAL::Random_points_in_square_2 Random_points_iterator; -typedef CGAL::Counting_iterator N_Random_points_iterator; -typedef CGAL::Search_traits_2 Traits; -typedef Point_with_info_helper::type Point_with_info; -typedef Point_property_map Ppmap; -typedef CGAL::Search_traits_adapter Traits_with_info; +typedef CGAL::Simple_cartesian K; +typedef K::FT FT; +typedef K::Point_2 Point; +typedef K::Vector_2 Vector; +typedef K::Iso_rectangle_2 Iso_rectangle; + +typedef CGAL::Random_points_in_square_2 Random_points_iterator; +typedef CGAL::Counting_iterator N_Random_points_iterator; +typedef CGAL::Search_traits_2 Traits; +typedef Point_with_info_helper::type Point_with_info; +typedef Point_property_map Ppmap; +typedef CGAL::Search_traits_adapter Traits_with_info; template -void run(std::list all_points) +void run_with_fuzziness(std::list all_points, + const Point& p, const Point& q, + const FT fuzziness, + CGAL::Random& rnd) { typedef CGAL::Fuzzy_iso_box Fuzzy_box; + std::cout << "test with box: [" << p << " || " << q << "] and eps: " << fuzziness << "... "; + + // test the results of the approximate query + Iso_rectangle inner_ic(p + fuzziness*Vector(1,1), q - fuzziness*Vector(1,1)); + Iso_rectangle outer_ic(p - fuzziness*Vector(1,1), q + fuzziness*Vector(1,1)); + + // If the fuziness is greater than half of the largest dimension of the box, + // then the inner box does not exist + const FT max_box_edge_length = (std::max)(q[1] - p[1], q[0] - p[0]); + const bool is_inner_c_empty = (fuzziness > 0.5 * max_box_edge_length); + if(is_inner_c_empty) + std::cout << " (empty inner box)... "; + + // Insert a bunch of points on the boundary of the inner approximation + std::size_t N = all_points.size(); + + if(!is_inner_c_empty) + { + for(std::size_t i=0, max=N/10; i tree( - boost::make_transform_iterator(all_points.begin(),Create_point_with_info()), - boost::make_transform_iterator(all_points.end(),Create_point_with_info()) + boost::make_transform_iterator(all_points.begin(), Create_point_with_info()), + boost::make_transform_iterator(all_points.end(), Create_point_with_info()) ); - Point p(0.1, 0.2); - Point q(0.3, 0.5); + tree.search(CGAL::Emptyset_iterator(), Fuzzy_box(p,q)); //test compilation when Point != Traits::Point_d + typename SearchTraits::Point_d pp(p); typename SearchTraits::Point_d qq(q); - - Iso_rectangle ic(p,q); - - Fuzzy_box default_range(pp,qq); - + // approximate range searching std::list result; - // Searching the box ic - tree.search( std::back_inserter( result ), default_range); + Fuzzy_box approximate_range(pp, qq, fuzziness); + tree.search(std::back_inserter(result), approximate_range); + std::cout << result.size() << " hits... Verifying correctness..."; - tree.search(CGAL::Emptyset_iterator(), Fuzzy_box(p,q) ); //test compilation when Point != Traits::Point_d - - // test the results of the default query - std::list copy_all_points(all_points); - for (typename std::list::iterator pt=result.begin(); (pt != result.end()); ++pt) { - assert(! ic.has_on_unbounded_side(get_point(*pt)) || ic.has_on_boundary(get_point(*pt))); - copy_all_points.remove(get_point(*pt)); - } - - for (std::list::iterator pt=copy_all_points.begin(); (pt != copy_all_points.end()); ++pt) { - assert(ic.has_on_unbounded_side(*pt) || ic.has_on_boundary(*pt)); - } - - - result.clear(); - // approximate range searching using value 0.1 for fuzziness parameter - Fuzzy_box approximate_range(pp,qq,0.05); - Iso_rectangle inner_ic(p+ 0.05*Vector(1,1),q-0.05*Vector(1,1)); - Iso_rectangle outer_ic(p- 0.05*Vector(1,1),q+0.05*Vector(1,1)); - - tree.search(std::back_inserter( result ), approximate_range); - // test the results of the approximate query - for (typename std::list::iterator pt=result.begin(); (pt != result.end()); ++pt) { - // a point we found may be slighlty outside the isorectangle - assert(! outer_ic.has_on_unbounded_side(get_point(*pt)) || outer_ic.has_on_boundary(get_point(*pt))); + for (typename std::list::iterator pt=result.begin(); (pt != result.end()); ++pt) + { + // a point can only be reported if it is in the outer box + bool is_correct = outer_ic.has_on_bounded_side(get_point(*pt)) || outer_ic.has_on_boundary(get_point(*pt)); + if(!is_correct) + std::cout << get_point(*pt) << " should have not been reported" << std::endl; + assert(is_correct); all_points.remove(get_point(*pt)); } - for (std::list::iterator pt=all_points.begin(); (pt != all_points.end()); ++pt) { - assert(inner_ic.has_on_unbounded_side(*pt) || inner_ic.has_on_boundary(*pt)); + // nothing to test if the inner box is empty because everything is on the unbounded side + if(!is_inner_c_empty) + { + for (std::list::iterator pt=all_points.begin(); (pt != all_points.end()); ++pt) + { + // all points that have not been reported must be outside the inner box + bool is_correct = inner_ic.has_on_unbounded_side(*pt); + if(!is_correct) + std::cout << *pt << " should have been reported" << std::endl; + + assert(is_correct); + } } + std::cout << "done" << std::endl; } -int main() { +template +void run(std::list all_points, // intentional copy + CGAL::Random& rnd) +{ + // bigger box + Point p0(-10., -10.); + Point q0( 10., 10.); + // a subset + Point p1(-CGAL_PI/10., -CGAL_PI/10.); + Point q1( CGAL_PI/10., CGAL_PI/10.); + + // another subset + Point p2(0.1, 0.2); + Point q2(0.3, 0.4); + + // degenerate + Point p3(0., 0.); + Point q3(0., 0.); + + run_with_fuzziness(all_points, p0, q0, 0. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, p0, q0, 0.1 /*fuzziness*/, rnd); + run_with_fuzziness(all_points, p0, q0, 1. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, p0, q0, 10. /*fuzziness*/, rnd); + + run_with_fuzziness(all_points, p1, q1, 0. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, p1, q1, 0.1 /*fuzziness*/, rnd); + run_with_fuzziness(all_points, p1, q1, 1. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, p1, q1, 10. /*fuzziness*/, rnd); + + run_with_fuzziness(all_points, p2, q2, 0. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, p2, q2, 0.1 /*fuzziness*/, rnd); + run_with_fuzziness(all_points, p2, q2, 0.4 /*fuzziness*/, rnd); + + run_with_fuzziness(all_points, p3, q3, 0. /*fuzziness*/, rnd); + run_with_fuzziness(all_points, p3, q3, 0.33 /*fuzziness*/, rnd); + run_with_fuzziness(all_points, p3, q3, 1. /*fuzziness*/, rnd); +} + +int main() +{ const int N=10000; + CGAL::Random rnd = CGAL::get_default_random(); + std::cout << "seed: " << rnd.get_seed() << std::endl; + // generator for random data points in the square ( (-1,-1), (1,1) ) - Random_points_iterator rpit( 1.0); + Random_points_iterator rpit(1.0, rnd); // construct list containing N random points std::list all_points(N_Random_points_iterator(rpit,0), - N_Random_points_iterator(N)); + N_Random_points_iterator(N)); - run(all_points); - run(all_points); + // add some interesting points + all_points.push_back(Point(0., 0.)); + all_points.push_back(Point(-CGAL_PI/10.+0.1, -CGAL_PI/10.+0.1)); + all_points.push_back(Point(1., 1.)); + all_points.push_back(Point(0., 1.)); + all_points.push_back(Point(0.3, 0.4)); + all_points.push_back(Point(0.2, 0.3)); + all_points.push_back(Point(0., 0.1)); + + run(all_points, rnd); + run(all_points, rnd); return 0; } diff --git a/Spatial_searching/test/Spatial_searching/Point_with_info.h b/Spatial_searching/test/Spatial_searching/Point_with_info.h index 48557ff6cdd..9b49e89a418 100644 --- a/Spatial_searching/test/Spatial_searching/Point_with_info.h +++ b/Spatial_searching/test/Spatial_searching/Point_with_info.h @@ -1,4 +1,5 @@ -#include +#include +#include template struct My_point_with_info @@ -22,11 +23,11 @@ struct Point_property_map{ typedef Point value_type; typedef const value_type& reference; typedef const My_point_with_info& key_type; - typedef boost::lvalue_property_map_tag category; + typedef boost::lvalue_property_map_tag category; reference operator[](key_type k) const {return k.point();} - friend reference get(const Point_property_map& ppmap, key_type i) + friend reference get(const Point_property_map& ppmap, key_type i) {return ppmap[i];} }; @@ -37,11 +38,11 @@ template const Point& get_point(const My_point_with_info& p) {return get(Point_property_map(),p);} template -struct Create_point_with_info : public CGAL::unary_function{ +struct Create_point_with_info : public CGAL::cpp98::unary_function{ const Point& operator() (const Point& p) const { return p; } }; template -struct Create_point_with_info > : public CGAL::unary_function >{ +struct Create_point_with_info > : public CGAL::cpp98::unary_function >{ My_point_with_info operator() (const Point& p) const { return My_point_with_info(p); } }; diff --git a/Spatial_searching/test/Spatial_searching/Search_traits_adapter_with_identity_map.cpp b/Spatial_searching/test/Spatial_searching/Search_traits_adapter_with_identity_map.cpp new file mode 100644 index 00000000000..00e66ca1d0f --- /dev/null +++ b/Spatial_searching/test/Spatial_searching/Search_traits_adapter_with_identity_map.cpp @@ -0,0 +1,38 @@ +#include +#include +#include +#include +#include +#include +#include + +typedef CGAL::Simple_cartesian Kernel; +typedef Kernel::Point_2 Point_2; +typedef CGAL::Random_points_in_disc_2 Random_points; + +typedef CGAL::Identity_property_map Point_map; +typedef CGAL::Search_traits_2 Search_base; +typedef CGAL::Search_traits_adapter Search_traits; +typedef CGAL::Fuzzy_sphere Fuzzy_circle; +typedef CGAL::Kd_tree Tree; + +int main () +{ + Random_points rdpts; + std::vector pts; + for (std::size_t i = 0; i < 50; ++ i) + pts.push_back (*(rdpts ++)); + + Tree tree (pts.begin(), pts.end()); + + Point_2 center(0., 0.); + Fuzzy_circle circle (center, 0.5); + std::vector result; + tree.search(std::back_inserter(result), circle); + std::cout << "The points in the fuzzy circle centered at (0., 0.) "; + std::cout << "with fuzzy radius (0.5) are: " << std::endl; + for (std::size_t i = 0; i < result.size(); ++ i) + std::cout << " * " << result[i] << std::endl; + + return 0; +} diff --git a/Spatial_sorting/include/CGAL/Hilbert_sort_median_2.h b/Spatial_sorting/include/CGAL/Hilbert_sort_median_2.h index c6f98d975f0..9a10f2a7b9b 100644 --- a/Spatial_sorting/include/CGAL/Hilbert_sort_median_2.h +++ b/Spatial_sorting/include/CGAL/Hilbert_sort_median_2.h @@ -33,8 +33,8 @@ namespace internal { template struct Hilbert_cmp_2 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { typedef typename K::Point_2 Point; K k; @@ -47,8 +47,8 @@ namespace internal { template struct Hilbert_cmp_2 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { typedef typename K::Point_2 Point; K k; @@ -61,8 +61,8 @@ namespace internal { template struct Hilbert_cmp_2 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { typedef typename K::Point_2 Point; K k; diff --git a/Spatial_sorting/include/CGAL/Hilbert_sort_median_3.h b/Spatial_sorting/include/CGAL/Hilbert_sort_median_3.h index 7049df39fbc..909d6716ef2 100644 --- a/Spatial_sorting/include/CGAL/Hilbert_sort_median_3.h +++ b/Spatial_sorting/include/CGAL/Hilbert_sort_median_3.h @@ -33,8 +33,8 @@ namespace internal { template struct Hilbert_cmp_3 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { typedef typename K::Point_3 Point; K k; @@ -47,8 +47,8 @@ namespace internal { template struct Hilbert_cmp_3 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { typedef typename K::Point_3 Point; K k; @@ -61,8 +61,8 @@ namespace internal { template struct Hilbert_cmp_3 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { typedef typename K::Point_3 Point; K k; @@ -75,8 +75,8 @@ namespace internal { template struct Hilbert_cmp_3 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { typedef typename K::Point_3 Point; K k; diff --git a/Spatial_sorting/include/CGAL/Hilbert_sort_median_d.h b/Spatial_sorting/include/CGAL/Hilbert_sort_median_d.h index 4b560b62aed..3e1748801f4 100644 --- a/Spatial_sorting/include/CGAL/Hilbert_sort_median_d.h +++ b/Spatial_sorting/include/CGAL/Hilbert_sort_median_d.h @@ -34,8 +34,8 @@ namespace internal { template struct Hilbert_cmp_d - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { typedef typename K::Point_d Point; K k; diff --git a/Spatial_sorting/include/CGAL/Hilbert_sort_middle_2.h b/Spatial_sorting/include/CGAL/Hilbert_sort_middle_2.h index 90e8335ed20..c44a5ad2c8d 100644 --- a/Spatial_sorting/include/CGAL/Hilbert_sort_middle_2.h +++ b/Spatial_sorting/include/CGAL/Hilbert_sort_middle_2.h @@ -34,8 +34,8 @@ namespace internal { template struct Fixed_hilbert_cmp_2 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { typedef typename K::Point_2 Point; K k; @@ -49,8 +49,8 @@ namespace internal { template struct Fixed_hilbert_cmp_2 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { typedef typename K::Point_2 Point; K k; @@ -64,8 +64,8 @@ namespace internal { template struct Fixed_hilbert_cmp_2 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { typedef typename K::Point_2 Point; K k; diff --git a/Spatial_sorting/include/CGAL/Hilbert_sort_middle_3.h b/Spatial_sorting/include/CGAL/Hilbert_sort_middle_3.h index a464a223f43..9fb33fe2e78 100644 --- a/Spatial_sorting/include/CGAL/Hilbert_sort_middle_3.h +++ b/Spatial_sorting/include/CGAL/Hilbert_sort_middle_3.h @@ -33,8 +33,8 @@ namespace internal { template struct Fixed_hilbert_cmp_3 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { typedef typename K::Point_3 Point; K k; @@ -48,8 +48,8 @@ namespace internal { template struct Fixed_hilbert_cmp_3 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { typedef typename K::Point_3 Point; K k; @@ -63,8 +63,8 @@ namespace internal { template struct Fixed_hilbert_cmp_3 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { typedef typename K::Point_3 Point; K k; @@ -78,8 +78,8 @@ namespace internal { template struct Fixed_hilbert_cmp_3 - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { typedef typename K::Point_3 Point; K k; diff --git a/Spatial_sorting/include/CGAL/Hilbert_sort_middle_d.h b/Spatial_sorting/include/CGAL/Hilbert_sort_middle_d.h index ecb321a75f7..9ff0882ae5b 100644 --- a/Spatial_sorting/include/CGAL/Hilbert_sort_middle_d.h +++ b/Spatial_sorting/include/CGAL/Hilbert_sort_middle_d.h @@ -33,7 +33,7 @@ namespace internal { template struct Fixed_hilbert_cmp_d - : public CGAL::binary_function { typedef typename K::Point_d Point; diff --git a/Straight_skeleton_2/include/CGAL/Straight_skeleton_builder_2.h b/Straight_skeleton_2/include/CGAL/Straight_skeleton_builder_2.h index 90fc4d9e4c8..cec7ff2855c 100644 --- a/Straight_skeleton_2/include/CGAL/Straight_skeleton_builder_2.h +++ b/Straight_skeleton_2/include/CGAL/Straight_skeleton_builder_2.h @@ -214,7 +214,7 @@ private : typedef std::vector MultinodeVector ; - struct Halfedge_ID_compare : CGAL::binary_function + struct Halfedge_ID_compare : CGAL::cpp98::binary_function { bool operator() ( Halfedge_handle const& aA, Halfedge_handle const& aB ) const { @@ -231,7 +231,7 @@ public: private : - class Event_compare : public CGAL::binary_function + class Event_compare : public CGAL::cpp98::binary_function { public: diff --git a/Subdivision_method_3/include/CGAL/Subdivision_method_3/internal/subdivision_hosts_impl_3.h b/Subdivision_method_3/include/CGAL/Subdivision_method_3/internal/subdivision_hosts_impl_3.h index cf467a3112d..2c93c17e0c3 100644 --- a/Subdivision_method_3/include/CGAL/Subdivision_method_3/internal/subdivision_hosts_impl_3.h +++ b/Subdivision_method_3/include/CGAL/Subdivision_method_3/internal/subdivision_hosts_impl_3.h @@ -173,7 +173,7 @@ void PQQ_1step(Poly& p, VertexPointMap vpm, Mask mask) { for (std::size_t i = 0; i < num_v; i++, ++vitr) put(vpm, *vitr, vertex_point_buffer[i]); -// CGAL_postcondition(p.is_valid()); + CGAL_postcondition(CGAL::is_valid_polygon_mesh(p)); delete []vertex_point_buffer; } @@ -277,7 +277,7 @@ void PTQ_1step(Poly& p, VertexPointMap vpm, Mask mask) { for (std::size_t i = 0; i < num_v; i++, ++vitr) put(vpm, *vitr, vertex_point_buffer[i]); -// CGAL_postcondition(p.is_valid()); + CGAL_postcondition(CGAL::is_valid_polygon_mesh(p)); delete []vertex_point_buffer; } @@ -527,7 +527,7 @@ void Sqrt3_1step(Poly& p, VertexPointMap vpm, Mask mask, } } -// CGAL_postcondition(p.is_valid()); + CGAL_postcondition(CGAL::is_valid_polygon_mesh(p)); delete []cpt; } diff --git a/Subdivision_method_3/test/Subdivision_method_3/test_Subdivision_method_3.cpp b/Subdivision_method_3/test/Subdivision_method_3/test_Subdivision_method_3.cpp index 9250848883a..7b0e8f399e5 100644 --- a/Subdivision_method_3/test/Subdivision_method_3/test_Subdivision_method_3.cpp +++ b/Subdivision_method_3/test/Subdivision_method_3/test_Subdivision_method_3.cpp @@ -58,7 +58,7 @@ void test_Subdivision_surface_3() { mesh >> P; Subdivision_method_3::CatmullClark_subdivision(P,TEST_DEPTH); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } // test Catmull-Clark subdivision on 'opened' quad mesh @@ -69,7 +69,7 @@ void test_Subdivision_surface_3() { mesh >> P; Subdivision_method_3::CatmullClark_subdivision(P,TEST_DEPTH); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } @@ -81,7 +81,7 @@ void test_Subdivision_surface_3() { mesh >> P; Subdivision_method_3::Loop_subdivision(P,TEST_DEPTH); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } // test Loop subdivision on 'opened' tri mesh @@ -92,7 +92,7 @@ void test_Subdivision_surface_3() { mesh >> P; Subdivision_method_3::Loop_subdivision(P,TEST_DEPTH); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } // test Doo-Sabin subdivision on general mesh @@ -103,7 +103,7 @@ void test_Subdivision_surface_3() { mesh >> P; Subdivision_method_3::DooSabin_subdivision(P,TEST_DEPTH); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } // test Sqrt-3 subdivision on tri mesh @@ -114,7 +114,7 @@ void test_Subdivision_surface_3() { mesh >> P; Subdivision_method_3::Sqrt3_subdivision(P,TEST_DEPTH); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } } @@ -130,7 +130,7 @@ void test_Subdivision_surface_3_SM() { mesh >> P; Subdivision_method_3::CatmullClark_subdivision(P,TEST_DEPTH); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } // test Catmull-Clark subdivision on 'opened' quad mesh @@ -141,7 +141,7 @@ void test_Subdivision_surface_3_SM() { mesh >> P; Subdivision_method_3::CatmullClark_subdivision(P,TEST_DEPTH); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } @@ -153,7 +153,7 @@ void test_Subdivision_surface_3_SM() { mesh >> P; Subdivision_method_3::Loop_subdivision(P,TEST_DEPTH); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } // test Loop subdivision on 'opened' tri mesh @@ -164,7 +164,7 @@ void test_Subdivision_surface_3_SM() { mesh >> P; Subdivision_method_3::Loop_subdivision(P,TEST_DEPTH); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } // test Doo-Sabin subdivision on general mesh @@ -175,7 +175,7 @@ void test_Subdivision_surface_3_SM() { mesh >> P; Subdivision_method_3::DooSabin_subdivision(P,TEST_DEPTH); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P, true)); } // test Doo-Sabin subdivision on 'opened' quad mesh @@ -186,7 +186,7 @@ void test_Subdivision_surface_3_SM() { mesh >> P; Subdivision_method_3::DooSabin_subdivision(P,TEST_DEPTH); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } // test Sqrt-3 subdivision on tri mesh @@ -197,7 +197,7 @@ void test_Subdivision_surface_3_SM() { mesh >> P; Subdivision_method_3::Sqrt3_subdivision(P,TEST_DEPTH); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } // test Sqrt-3 subdivision on 'opened' tri mesh @@ -208,7 +208,7 @@ void test_Subdivision_surface_3_SM() { mesh >> P; Subdivision_method_3::Sqrt3_subdivision(P,TEST_DEPTH); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } } @@ -225,7 +225,7 @@ void test_Subdivision_surface_3_SM_NP() { Subdivision_method_3::CatmullClark_subdivision(P,Subdivision_method_3::parameters::vertex_point_map(get(vertex_point, P)) .number_of_iterations(TEST_DEPTH)); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } // test Catmull-Clark subdivision on 'opened' quad mesh @@ -237,7 +237,7 @@ void test_Subdivision_surface_3_SM_NP() { Subdivision_method_3::CatmullClark_subdivision(P,Subdivision_method_3::parameters::vertex_point_map(get(vertex_point, P)) .number_of_iterations(TEST_DEPTH)); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } @@ -250,7 +250,7 @@ void test_Subdivision_surface_3_SM_NP() { Subdivision_method_3::Loop_subdivision(P,Subdivision_method_3::parameters::vertex_point_map(get(vertex_point, P)) .number_of_iterations(TEST_DEPTH)); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } // test Loop subdivision on 'opened' tri mesh @@ -262,7 +262,7 @@ void test_Subdivision_surface_3_SM_NP() { Subdivision_method_3::Loop_subdivision(P,Subdivision_method_3::parameters::vertex_point_map(get(vertex_point, P)) .number_of_iterations(TEST_DEPTH)); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } // test Doo-Sabin subdivision on 'opened' tri mesh @@ -274,7 +274,7 @@ void test_Subdivision_surface_3_SM_NP() { Subdivision_method_3::DooSabin_subdivision(P,Subdivision_method_3::parameters::vertex_point_map(get(vertex_point, P)) .number_of_iterations(TEST_DEPTH)); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } // test Doo-Sabin subdivision on 'opened' quad mesh @@ -285,7 +285,7 @@ void test_Subdivision_surface_3_SM_NP() { mesh >> P; Subdivision_method_3::DooSabin_subdivision(P,TEST_DEPTH); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } // test Sqrt-3 subdivision on tri mesh @@ -298,7 +298,7 @@ void test_Subdivision_surface_3_SM_NP() { Subdivision_method_3::Sqrt3_subdivision(P,Subdivision_method_3::parameters::vertex_point_map(get(vertex_point, P)) .number_of_iterations(TEST_DEPTH)); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } // test Sqrt-3 subdivision on 'opened' tri mesh @@ -314,7 +314,7 @@ void test_Subdivision_surface_3_SM_NP() { std::ofstream out("out_0.off"); out << P; - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } // test Sqrt-3 subdivision on 'opened' tri mesh & with external property map @@ -347,7 +347,7 @@ void test_Subdivision_surface_3_SM_NP() { Subdivision_method_3::parameters::vertex_point_map(apm) .number_of_iterations(TEST_DEPTH)); - assert(P.is_valid()); + assert(CGAL::is_valid_polygon_mesh(P)); } } diff --git a/Surface_mesh/doc/Surface_mesh/PackageDescription.txt b/Surface_mesh/doc/Surface_mesh/PackageDescription.txt index 58ead2eda6c..1707c8a7a3f 100644 --- a/Surface_mesh/doc/Surface_mesh/PackageDescription.txt +++ b/Surface_mesh/doc/Surface_mesh/PackageDescription.txt @@ -1,6 +1,14 @@ /// \defgroup PkgSurface_mesh Surface Mesh Reference +/*! Draw. + \code + #include + \endcode +*/ +/// \defgroup PkgDrawSurfaceMesh Draw a Surface Mesh +/// \ingroup PkgSurface_mesh + /*! \addtogroup PkgSurface_mesh \cgalPkgDescriptionBegin{Surface Mesh,PkgSurfaceMeshSummary} @@ -31,5 +39,8 @@ and faces is much simpler and can be used at runtime and not at compile time.} - `CGAL::Surface_mesh

` +### Draw a Surface Mesh ### +- `CGAL::draw` + */ diff --git a/Surface_mesh/doc/Surface_mesh/Surface_mesh.txt b/Surface_mesh/doc/Surface_mesh/Surface_mesh.txt index 395ec2ca8b1..06b7c0dc14d 100644 --- a/Surface_mesh/doc/Surface_mesh/Surface_mesh.txt +++ b/Surface_mesh/doc/Surface_mesh/Surface_mesh.txt @@ -344,6 +344,20 @@ refering to the right vertices. \subsection SubsectionSurfaceMeshMemoryManagementExample Example \cgalExample{Surface_mesh/sm_memory.cpp} +\section SurfaceMeshDraw Draw a Surface Mesh +\anchor ssecDrawSurfaceMesh + +A surface mesh can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given surface mesh. The function is blocking, that is the program continues as soon as the user closes the window. + +\cgalExample{Surface_mesh/draw_surface_mesh.cpp} + +This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. + +\cgalFigureBegin{fig_draw_surface_mesh,draw_surface_mesh.png} +Result of the run of the draw_surface_mesh program. A window shows the surface mesh and allows to navigate through the 3D scene. +\cgalFigureEnd + + \section sectionSurfaceMeshImplementation Implementation Details As integer type for the indices we have chosen `boost::uint32_t`. On 64 bit operating systems they diff --git a/Surface_mesh/doc/Surface_mesh/examples.txt b/Surface_mesh/doc/Surface_mesh/examples.txt index 7d76ae3218a..b19e4dfa646 100644 --- a/Surface_mesh/doc/Surface_mesh/examples.txt +++ b/Surface_mesh/doc/Surface_mesh/examples.txt @@ -10,4 +10,5 @@ \example Surface_mesh/sm_do_intersect.cpp \example Surface_mesh/sm_aabbtree.cpp @endcond +\example Surface_mesh/draw_surface_mesh.cpp */ diff --git a/Surface_mesh/doc/Surface_mesh/fig/draw_surface_mesh.png b/Surface_mesh/doc/Surface_mesh/fig/draw_surface_mesh.png new file mode 100644 index 00000000000..1c0800bfe46 Binary files /dev/null and b/Surface_mesh/doc/Surface_mesh/fig/draw_surface_mesh.png differ diff --git a/Surface_mesh/examples/Surface_mesh/CMakeLists.txt b/Surface_mesh/examples/Surface_mesh/CMakeLists.txt index cdd0587bf7f..6170d1bb2b7 100644 --- a/Surface_mesh/examples/Surface_mesh/CMakeLists.txt +++ b/Surface_mesh/examples/Surface_mesh/CMakeLists.txt @@ -6,8 +6,16 @@ project( Surface_mesh_Examples ) cmake_minimum_required(VERSION 2.8.11) +if(NOT POLICY CMP0070 AND POLICY CMP0053) + # Only set CMP0053 to OLD with CMake<3.10, otherwise there is a warning. + cmake_policy(SET CMP0053 OLD) +endif() -find_package(CGAL QUIET) +find_package(CGAL COMPONENTS Qt5) + +if(CGAL_Qt5_FOUND) + add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS) +endif() if ( CGAL_FOUND ) @@ -28,6 +36,11 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "sm_memory.cpp" ) create_single_source_cgal_program( "sm_properties.cpp" ) + create_single_source_cgal_program("draw_surface_mesh.cpp") + if(CGAL_Qt5_FOUND ) + target_link_libraries(draw_surface_mesh PUBLIC CGAL::CGAL_Qt5) + endif() + else() message(STATUS "This program requires the CGAL library, and will not be compiled.") diff --git a/Surface_mesh/examples/Surface_mesh/cube.off b/Surface_mesh/examples/Surface_mesh/cube.off deleted file mode 100644 index b1afa5a6858..00000000000 --- a/Surface_mesh/examples/Surface_mesh/cube.off +++ /dev/null @@ -1,22 +0,0 @@ -OFF -8 12 0 --1 -1 -1 --1 1 -1 -1 1 -1 -1 -1 -1 --1 -1 1 --1 1 1 -1 1 1 -1 -1 1 -3 0 1 3 -3 3 1 2 -3 0 4 1 -3 1 4 5 -3 3 2 7 -3 7 2 6 -3 4 0 3 -3 7 4 3 -3 6 4 7 -3 6 5 4 -3 1 5 6 -3 2 1 6 diff --git a/Surface_mesh/examples/Surface_mesh/draw_surface_mesh.cpp b/Surface_mesh/examples/Surface_mesh/draw_surface_mesh.cpp new file mode 100644 index 00000000000..4735193c89f --- /dev/null +++ b/Surface_mesh/examples/Surface_mesh/draw_surface_mesh.cpp @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +typedef CGAL::Simple_cartesian Kernel; +typedef Kernel::Point_3 Point; +typedef CGAL::Surface_mesh Mesh; + +int main(int argc, char* argv[]) +{ + Mesh sm1; + std::ifstream in1((argc>1)?argv[1]:"data/triangle.off"); + in1 >> sm1; + + CGAL::draw(sm1); + + return EXIT_SUCCESS; +} diff --git a/Surface_mesh/examples/Surface_mesh/sm_join.cpp b/Surface_mesh/examples/Surface_mesh/sm_join.cpp index c892bfc4cd9..e787eb66c70 100644 --- a/Surface_mesh/examples/Surface_mesh/sm_join.cpp +++ b/Surface_mesh/examples/Surface_mesh/sm_join.cpp @@ -36,5 +36,4 @@ int main(int argc, char* argv[]) std::cout << sm1 << std::endl; - } diff --git a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h index aa410a18afb..8e0059e0211 100644 --- a/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h +++ b/Surface_mesh/include/CGAL/Surface_mesh/Surface_mesh.h @@ -2649,7 +2649,7 @@ namespace std { template <> struct hash - : public CGAL::unary_function { + : public CGAL::cpp98::unary_function { std::size_t operator()(const CGAL::SM_Halfedge_index& i) const { @@ -2659,7 +2659,7 @@ namespace std { template <> struct hash - : public CGAL::unary_function { + : public CGAL::cpp98::unary_function { std::size_t operator()(const CGAL::SM_Vertex_index& i) const { @@ -2669,7 +2669,7 @@ namespace std { template <> struct hash - : public CGAL::unary_function { + : public CGAL::cpp98::unary_function { std::size_t operator()(const CGAL::SM_Face_index& i) const { @@ -2679,7 +2679,7 @@ namespace std { template <> struct hash - : public CGAL::unary_function { + : public CGAL::cpp98::unary_function { std::size_t operator()(const CGAL::SM_Edge_index& i) const { diff --git a/Surface_mesh/include/CGAL/boost/graph/graph_traits_Surface_mesh.h b/Surface_mesh/include/CGAL/boost/graph/graph_traits_Surface_mesh.h index 9f79653b7f1..f42cd99887e 100644 --- a/Surface_mesh/include/CGAL/boost/graph/graph_traits_Surface_mesh.h +++ b/Surface_mesh/include/CGAL/boost/graph/graph_traits_Surface_mesh.h @@ -522,12 +522,6 @@ add_face(InputIterator begin, InputIterator end, CGAL::Surface_mesh

& sm) return sm.add_face(v); } -template -bool is_valid(const CGAL::Surface_mesh

& sm, bool verbose = false) -{ - return sm.is_valid(verbose); -} - template void normalize_border(const CGAL::Surface_mesh

&) {} diff --git a/Surface_mesh/include/CGAL/draw_surface_mesh.h b/Surface_mesh/include/CGAL/draw_surface_mesh.h new file mode 100644 index 00000000000..3e5f602d94c --- /dev/null +++ b/Surface_mesh/include/CGAL/draw_surface_mesh.h @@ -0,0 +1,252 @@ +// Copyright (c) 2018 GeometryFactory (France) +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// Author(s) : Guillaume Damiand + +#ifndef CGAL_DRAW_SURFACE_MESH_H +#define CGAL_DRAW_SURFACE_MESH_H + +#ifdef DOXYGEN_RUNNING + +/*! +\ingroup PkgDrawSurfaceMesh + +Open a new window and draw `asm`, an instance of the `CGAL::Surface_mesh` class. The function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. +\tparam SM an instance of the `CGAL::Surface_mesh` class. +\param asm the surface mesh to draw. + +*/ +template +void draw(const SM& asm); + +#else // DOXYGEN_RUNNING + +#include +#include + +#ifdef CGAL_USE_BASIC_VIEWER + +#include + +namespace CGAL +{ + +// Default color functor; user can change it to have its own face color +struct DefaultColorFunctorSM +{ + template + static CGAL::Color run(const SM&, + typename SM::Face_index fh) + { + if (fh==boost::graph_traits::null_face()) // use to get the mono color + return CGAL::Color(100, 125, 200); // R G B between 0-255 + + CGAL::Random random((unsigned int)fh); + return get_random_color(random); + } +}; + +template +class SimpleSurfaceMeshViewerQt : public Basic_viewer_qt +{ + typedef Basic_viewer_qt Base; + typedef typename SM::Point Point; + typedef typename CGAL::Kernel_traits::Kernel Kernel; + typedef typename SM::Vertex_index vertex_descriptor; + typedef typename SM::Face_index face_descriptor; + typedef typename SM::Edge_index edge_descriptor; + typedef typename SM::Halfedge_index halfedge_descriptor; + +public: + /// Construct the viewer. + /// @param amesh the surface mesh to view + /// @param title the title of the window + /// @param anofaces if true, do not draw faces (faces are not computed; this can be + /// usefull for very big object where this time could be long) + SimpleSurfaceMeshViewerQt(QWidget* parent, + const SM& amesh, + const char* title="Basic Surface_mesh Viewer", + bool anofaces=false, + const ColorFunctor& fcolor=ColorFunctor()) : + // First draw: no vertex; edges, faces; mono-color; inverse normal + Base(parent, title, false, true, true, true, false), + sm(amesh), + m_nofaces(anofaces), + m_fcolor(fcolor) + { + compute_elements(); + } + +protected: + void compute_face(face_descriptor fh) + { + CGAL::Color c=m_fcolor.run(sm, fh); + face_begin(c); + halfedge_descriptor hd=sm.halfedge(fh); + do + { + add_point_in_face(sm.point(sm.source(hd)), get_vertex_normal(hd)); + hd=sm.next(hd); + } + while(hd!=sm.halfedge(fh)); + face_end(); + } + + void compute_edge(edge_descriptor e) + { + add_segment(sm.point(sm.source(sm.halfedge(e))), + sm.point(sm.target(sm.halfedge(e)))); + } + + void compute_vertex(vertex_descriptor vh) + { add_point(sm.point(vh)); } + + void compute_elements() + { + clear(); + + if (!m_nofaces) + { + for (typename SM::Face_range::iterator f=sm.faces().begin(); + f!=sm.faces().end(); ++f) + { + if (*f!=boost::graph_traits::null_face()) + { compute_face(*f); } + } + } + + for (typename SM::Edge_range::iterator e=sm.edges().begin(); + e!=sm.edges().end(); ++e) + { compute_edge(*e); } + + for (typename SM::Vertex_range::iterator v=sm.vertices().begin(); + v!=sm.vertices().end(); ++v) + { compute_vertex(*v); } + } + + virtual void keyPressEvent(QKeyEvent *e) + { + // Test key pressed: + // const ::Qt::KeyboardModifiers modifiers = e->modifiers(); + // if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) { ... } + + // Call: * compute_elements() if the model changed, followed by + // * redraw() if some viewing parameters changed that implies some + // modifications of the buffers + // (eg. type of normal, color/mono) + // * update() just to update the drawing + + // Call the base method to process others/classicals key + Base::keyPressEvent(e); + } + +protected: + typename Kernel::Vector_3 get_face_normal(halfedge_descriptor he) + { + typename Kernel::Vector_3 normal=CGAL::NULL_VECTOR; + halfedge_descriptor end=he; + unsigned int nb=0; + do + { + internal::newell_single_step_3(sm.point(sm.source(he)), + sm.point(sm.target(he)), normal); + ++nb; + he=sm.next(he); + } + while (he!=end); + assert(nb>0); + return (typename Kernel::Construct_scaled_vector_3()(normal, 1.0/nb)); + } + + typename Kernel::Vector_3 get_vertex_normal(halfedge_descriptor he) + { + typename Kernel::Vector_3 normal=CGAL::NULL_VECTOR; + halfedge_descriptor end=he; + do + { + if (!sm.is_border(he)) + { + typename Kernel::Vector_3 n=get_face_normal(he); + normal=typename Kernel::Construct_sum_of_vectors_3()(normal, n); + } + he=sm.next(sm.opposite(he)); + } + while (he!=end); + + if (!typename Kernel::Equal_3()(normal, CGAL::NULL_VECTOR)) + { normal=(typename Kernel::Construct_scaled_vector_3() + (normal, 1.0/CGAL::sqrt(normal.squared_length()))); } + + return normal; + } + +protected: + const SM& sm; + bool m_nofaces; + const ColorFunctor& m_fcolor; +}; + +template +void draw(const SM& amesh, + const char* title, + bool nofill, + const ColorFunctor& fcolor) +{ +#if defined(CGAL_TEST_SUITE) + bool cgal_test_suite=true; +#else + bool cgal_test_suite=false; +#endif + + if (!cgal_test_suite) + { + int argc=1; + const char* argv[2]={"surface_mesh_viewer","\0"}; + QApplication app(argc,const_cast(argv)); + SimpleSurfaceMeshViewerQt mainwindow(app.activeWindow(), + amesh, + title, + nofill, + fcolor); + mainwindow.show(); + app.exec(); + } +} + +template +void draw(const SM& amesh, const char* title, bool nofill) +{ + DefaultColorFunctorSM c; + draw(amesh, title, nofill, c); +} + +template +void draw(const SM& amesh, const char* title) +{ draw(amesh, title, false); } + +template +void draw(const SM& amesh) +{ draw(amesh, "Basic Surface_mesh Viewer"); } + +} // End namespace CGAL + +#endif // CGAL_USE_BASIC_VIEWER + +#endif // DOXYGEN_RUNNING + +#endif // CGAL_DRAW_SURFACE_MESH_H diff --git a/Surface_mesh/package_info/Surface_mesh/dependencies b/Surface_mesh/package_info/Surface_mesh/dependencies index c34f3a297ff..474db4e6713 100644 --- a/Surface_mesh/package_info/Surface_mesh/dependencies +++ b/Surface_mesh/package_info/Surface_mesh/dependencies @@ -4,6 +4,7 @@ Cartesian_kernel Circulator Distance_2 Distance_3 +GraphicsView Hash_map Installation Interval_support diff --git a/Surface_mesh_deformation/test/Surface_mesh_deformation/Cactus_deformation_session.cpp b/Surface_mesh_deformation/test/Surface_mesh_deformation/Cactus_deformation_session.cpp index 23d96f039f7..383b5cd2f66 100644 --- a/Surface_mesh_deformation/test/Surface_mesh_deformation/Cactus_deformation_session.cpp +++ b/Surface_mesh_deformation/test/Surface_mesh_deformation/Cactus_deformation_session.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include diff --git a/Surface_mesh_deformation/test/Surface_mesh_deformation/Cactus_performance_test.cpp b/Surface_mesh_deformation/test/Surface_mesh_deformation/Cactus_performance_test.cpp index 081c53030b2..6045e1cf4a7 100644 --- a/Surface_mesh_deformation/test/Surface_mesh_deformation/Cactus_performance_test.cpp +++ b/Surface_mesh_deformation/test/Surface_mesh_deformation/Cactus_performance_test.cpp @@ -6,7 +6,6 @@ #include #include -#include #include #include diff --git a/Surface_mesh_deformation/test/Surface_mesh_deformation/Surface_mesh_deformation_test_commons.h b/Surface_mesh_deformation/test/Surface_mesh_deformation/Surface_mesh_deformation_test_commons.h index 2650b7dbc91..b165ac6c6b2 100644 --- a/Surface_mesh_deformation/test/Surface_mesh_deformation/Surface_mesh_deformation_test_commons.h +++ b/Surface_mesh_deformation/test/Surface_mesh_deformation/Surface_mesh_deformation_test_commons.h @@ -1,6 +1,4 @@ -#include -#include - +#include #include #include #include diff --git a/Surface_mesh_deformation/test/Surface_mesh_deformation/Symmetry_test.cpp b/Surface_mesh_deformation/test/Surface_mesh_deformation/Symmetry_test.cpp index 6dddddf8008..cea63122867 100644 --- a/Surface_mesh_deformation/test/Surface_mesh_deformation/Symmetry_test.cpp +++ b/Surface_mesh_deformation/test/Surface_mesh_deformation/Symmetry_test.cpp @@ -8,7 +8,6 @@ #include #include #include -#include typedef CGAL::Simple_cartesian Kernel; typedef CGAL::Polyhedron_3 Polyhedron; diff --git a/Surface_mesh_segmentation/test/Surface_mesh_segmentation/Fast_sdf_calculation_test.cpp b/Surface_mesh_segmentation/test/Surface_mesh_segmentation/Fast_sdf_calculation_test.cpp index 3b1c54d11cd..4f6c44ed6c9 100644 --- a/Surface_mesh_segmentation/test/Surface_mesh_segmentation/Fast_sdf_calculation_test.cpp +++ b/Surface_mesh_segmentation/test/Surface_mesh_segmentation/Fast_sdf_calculation_test.cpp @@ -1,6 +1,5 @@ #include -#include -#include +#include #include #include diff --git a/Surface_mesh_segmentation/test/Surface_mesh_segmentation/Filters_test.cpp b/Surface_mesh_segmentation/test/Surface_mesh_segmentation/Filters_test.cpp index 831ce389984..e4897a0dd6c 100644 --- a/Surface_mesh_segmentation/test/Surface_mesh_segmentation/Filters_test.cpp +++ b/Surface_mesh_segmentation/test/Surface_mesh_segmentation/Filters_test.cpp @@ -1,8 +1,7 @@ #include #include -#include -#include +#include #include #include diff --git a/Surface_mesh_segmentation/test/Surface_mesh_segmentation/mesh_segmentation_test.cpp b/Surface_mesh_segmentation/test/Surface_mesh_segmentation/mesh_segmentation_test.cpp index ebd3e4019c6..2afde8999d9 100644 --- a/Surface_mesh_segmentation/test/Surface_mesh_segmentation/mesh_segmentation_test.cpp +++ b/Surface_mesh_segmentation/test/Surface_mesh_segmentation/mesh_segmentation_test.cpp @@ -1,6 +1,5 @@ #include -#include -#include +#include #include diff --git a/Surface_mesh_segmentation/test/Surface_mesh_segmentation/mesh_segmentation_test_using_boost.cpp b/Surface_mesh_segmentation/test/Surface_mesh_segmentation/mesh_segmentation_test_using_boost.cpp index 992203e964d..eaf9f8b1f81 100644 --- a/Surface_mesh_segmentation/test/Surface_mesh_segmentation/mesh_segmentation_test_using_boost.cpp +++ b/Surface_mesh_segmentation/test/Surface_mesh_segmentation/mesh_segmentation_test_using_boost.cpp @@ -1,8 +1,7 @@ #define CGAL_DO_NOT_USE_BOYKOV_KOLMOGOROV_MAXFLOW_SOFTWARE #include -#include -#include +#include #include diff --git a/Surface_mesh_segmentation/test/Surface_mesh_segmentation/test_compute_sdf_values_and_segment_exact_rational.cpp b/Surface_mesh_segmentation/test/Surface_mesh_segmentation/test_compute_sdf_values_and_segment_exact_rational.cpp index 80703d42805..36b3989e902 100644 --- a/Surface_mesh_segmentation/test/Surface_mesh_segmentation/test_compute_sdf_values_and_segment_exact_rational.cpp +++ b/Surface_mesh_segmentation/test/Surface_mesh_segmentation/test_compute_sdf_values_and_segment_exact_rational.cpp @@ -1,8 +1,7 @@ #include #include -#include +#include -#include #include #include diff --git a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_1.cpp b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_1.cpp index f5af383014e..457c5f951a0 100644 --- a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_1.cpp +++ b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_1.cpp @@ -9,9 +9,7 @@ #include #include -#include -#include #include #include diff --git a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_2.cpp b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_2.cpp index 8b5493eea39..5a895e77fc4 100644 --- a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_2.cpp +++ b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_2.cpp @@ -11,11 +11,8 @@ #include #include -#include #include -#include -#include #include #include diff --git a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_3.cpp b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_3.cpp index eb81aa1df7d..96af1eed022 100644 --- a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_3.cpp +++ b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_3.cpp @@ -2,12 +2,10 @@ #include #include -#include #include #include -#include #include #include diff --git a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_4.cpp b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_4.cpp index 87020292d7c..c6ab30e0fef 100644 --- a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_4.cpp +++ b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_4.cpp @@ -2,12 +2,10 @@ #include #include -#include #include #include -#include #include #include diff --git a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_5.cpp b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_5.cpp index a00e74fa66e..aea9ead5bd8 100644 --- a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_5.cpp +++ b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_test_5.cpp @@ -10,9 +10,7 @@ #include #include -#include -#include #include #include diff --git a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_traits_test.cpp b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_traits_test.cpp index d3e575d5e68..04744d1b3ac 100644 --- a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_traits_test.cpp +++ b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/Surface_mesh_shortest_path_traits_test.cpp @@ -2,14 +2,12 @@ #include #include -#include #include #include #include #include -#include #include #include diff --git a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/TestMesh.cpp b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/TestMesh.cpp index 2edc30b901c..89f57b80826 100644 --- a/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/TestMesh.cpp +++ b/Surface_mesh_shortest_path/test/Surface_mesh_shortest_path/TestMesh.cpp @@ -20,14 +20,12 @@ #include #include -#include #include #include #include #include -#include #include #include diff --git a/Surface_mesh_simplification/examples/Surface_mesh_simplification/edge_collapse_bounded_normal_change.cpp b/Surface_mesh_simplification/examples/Surface_mesh_simplification/edge_collapse_bounded_normal_change.cpp index 037d75c4c27..f46b2bfb847 100644 --- a/Surface_mesh_simplification/examples/Surface_mesh_simplification/edge_collapse_bounded_normal_change.cpp +++ b/Surface_mesh_simplification/examples/Surface_mesh_simplification/edge_collapse_bounded_normal_change.cpp @@ -2,8 +2,6 @@ #include #include #include -#include -#include // Simplification function #include diff --git a/Surface_mesh_simplification/test/Surface_mesh_simplification/basics.h b/Surface_mesh_simplification/test/Surface_mesh_simplification/basics.h index 6f3b1ae089d..0dc8b196a84 100644 --- a/Surface_mesh_simplification/test/Surface_mesh_simplification/basics.h +++ b/Surface_mesh_simplification/test/Surface_mesh_simplification/basics.h @@ -27,7 +27,6 @@ void Surface_simplification_external_trace( std::string s ) #include #include -#include #include #include @@ -35,7 +34,6 @@ void Surface_simplification_external_trace( std::string s ) #include #include -#include #include #include diff --git a/Surface_mesh_simplification/test/Surface_mesh_simplification/edge_collapse_topology.cpp b/Surface_mesh_simplification/test/Surface_mesh_simplification/edge_collapse_topology.cpp index e6c6d3d18ac..2501ead0069 100644 --- a/Surface_mesh_simplification/test/Surface_mesh_simplification/edge_collapse_topology.cpp +++ b/Surface_mesh_simplification/test/Surface_mesh_simplification/edge_collapse_topology.cpp @@ -3,9 +3,6 @@ #include #include -#include - -#include // Simplification function #include diff --git a/Surface_mesh_skeletonization/test/Surface_mesh_skeletonization/MCF_Skeleton_test.cpp b/Surface_mesh_skeletonization/test/Surface_mesh_skeletonization/MCF_Skeleton_test.cpp index 4467550ae86..63deba74b69 100644 --- a/Surface_mesh_skeletonization/test/Surface_mesh_skeletonization/MCF_Skeleton_test.cpp +++ b/Surface_mesh_skeletonization/test/Surface_mesh_skeletonization/MCF_Skeleton_test.cpp @@ -1,10 +1,8 @@ #include #include -#include #include #include #include -#include #include diff --git a/Surface_mesh_skeletonization/test/Surface_mesh_skeletonization/skeleton_connectivity_test.cpp b/Surface_mesh_skeletonization/test/Surface_mesh_skeletonization/skeleton_connectivity_test.cpp index 0fab0e9af72..4409100ab7e 100644 --- a/Surface_mesh_skeletonization/test/Surface_mesh_skeletonization/skeleton_connectivity_test.cpp +++ b/Surface_mesh_skeletonization/test/Surface_mesh_skeletonization/skeleton_connectivity_test.cpp @@ -1,10 +1,8 @@ #include #include -#include #include #include #include -#include #include diff --git a/Surface_mesher/demo/Surface_mesher/CMakeLists.txt b/Surface_mesher/demo/Surface_mesher/CMakeLists.txt index 36c68b41489..1882fe86c53 100644 --- a/Surface_mesher/demo/Surface_mesher/CMakeLists.txt +++ b/Surface_mesher/demo/Surface_mesher/CMakeLists.txt @@ -47,14 +47,9 @@ if ( CGAL_FOUND AND CGAL_Qt5_FOUND AND CGAL_ImageIO_FOUND) include( ${CGAL_USE_FILE} ) find_package(Qt5 QUIET COMPONENTS OpenGL Xml Svg) - find_package(QGLViewer ) find_package(OpenGL ) - if ( QGLVIEWER_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND OPENGL_GLU_FOUND ) - - - include_directories( ${QGLVIEWER_INCLUDE_DIR} ) - add_definitions(${QGLVIEWER_DEFINITIONS}) + if (Qt5_FOUND AND OPENGL_FOUND AND OPENGL_GLU_FOUND ) set( sources Raw_image_dialog.cpp colorlisteditor.cpp values_list.cpp mainwindow.cpp Surface_mesher.cpp viewer.cpp volume.cpp ) @@ -117,7 +112,6 @@ if ( CGAL_FOUND AND CGAL_Qt5_FOUND AND CGAL_ImageIO_FOUND) target_link_libraries( ${prj} PRIVATE CGAL::CGAL CGAL::CGAL_Qt5 CGAL::CGAL_ImageIO ${OPENGL_LIBRARIES} - ${QGLVIEWER_LIBRARIES} ${VTK_LIBS} ) include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake) @@ -125,10 +119,7 @@ if ( CGAL_FOUND AND CGAL_Qt5_FOUND AND CGAL_ImageIO_FOUND) include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake) cgal_add_compilation_test(${prj}) - - else( QGLVIEWER_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND OPENGL_GLU_FOUND ) - message(STATUS "NOTICE: This demo needs libQGLViewer, and will not be compiled.") - endif( QGLVIEWER_FOUND AND Qt5_FOUND AND OPENGL_FOUND AND OPENGL_GLU_FOUND ) + endif( Qt5_FOUND AND OPENGL_FOUND AND OPENGL_GLU_FOUND ) else(CGAL_FOUND AND CGAL_Qt5_FOUND AND CGAL_ImageIO_FOUND) if(RUNNING_CGAL_AUTO_TEST) # Just to avoid a warning from CMake if that variable is set on the command line... diff --git a/Surface_mesher/demo/Surface_mesher/mainwindow.cpp b/Surface_mesher/demo/Surface_mesher/mainwindow.cpp index bd4016a2482..c128f87d8c6 100644 --- a/Surface_mesher/demo/Surface_mesher/mainwindow.cpp +++ b/Surface_mesher/demo/Surface_mesher/mainwindow.cpp @@ -16,7 +16,7 @@ #include #include -#include +#include #include // std::max #include // std::sqrt diff --git a/Surface_mesher/demo/Surface_mesher/mainwindow.h b/Surface_mesher/demo/Surface_mesher/mainwindow.h index e32322fb14d..3cc0be06b50 100644 --- a/Surface_mesher/demo/Surface_mesher/mainwindow.h +++ b/Surface_mesher/demo/Surface_mesher/mainwindow.h @@ -8,10 +8,13 @@ class QDragEnterEvent; class QDropEvent; class Surface; -class QGLViewer; class QDoubleSpinBox; class QCloseEvent; +namespace CGAL{ +class QGLViewer; +} + class MainWindow : public CGAL::Qt::DemosMainWindow, public Ui::MainWindow { Q_OBJECT diff --git a/Surface_mesher/demo/Surface_mesher/polyhedral_surface.cpp b/Surface_mesher/demo/Surface_mesher/polyhedral_surface.cpp index 6d3d61f98dd..5ebff4a64b8 100644 --- a/Surface_mesher/demo/Surface_mesher/polyhedral_surface.cpp +++ b/Surface_mesher/demo/Surface_mesher/polyhedral_surface.cpp @@ -300,8 +300,8 @@ bool Polyhedral_surface::open(const QString& filename) % xcenter % ycenter % zcenter << boost::format(" span=(%1%,%2%,%3%)\n") % xdelta % ydelta % zdelta; - viewer->camera()->setSceneBoundingBox(qglviewer::Vec(xmin, ymin, zmin), - qglviewer::Vec(xmax, ymax, zmax)); + viewer->camera()->setSceneBoundingBox(CGAL::qglviewer::Vec(xmin, ymin, zmin), + CGAL::qglviewer::Vec(xmax, ymax, zmax)); viewer->setBackgroundColor(Qt::white); viewer->showEntireScene(); diff --git a/Surface_mesher/demo/Surface_mesher/viewer.cpp b/Surface_mesher/demo/Surface_mesher/viewer.cpp index 6618268d8d6..70d0ebe6cd4 100644 --- a/Surface_mesher/demo/Surface_mesher/viewer.cpp +++ b/Surface_mesher/demo/Surface_mesher/viewer.cpp @@ -1,10 +1,10 @@ #include "viewer.h" #include "surface.h" #include -#include +#include Viewer::Viewer(QWidget* parent) - : QGLViewer(parent), surface(0) + : CGAL::QGLViewer(parent), surface(0) { // Do not store state in a file setStateFileName(""); @@ -37,9 +37,9 @@ void Viewer::interpolateToFitBoundingBox(double xmin, double ymin, double zmin, Q_ASSERT_X(auto_resize, "Viewer::interpolateToFitBoundingBox", "cannot find action \"actionAuto_resize\""); if(auto_resize && auto_resize->isChecked()) { - qglviewer::Camera new_camera = *(camera ()); - new_camera.fitBoundingBox(qglviewer::Vec(xmin, ymin, zmin), - qglviewer::Vec(xmax, ymax, zmax)); + CGAL::qglviewer::Camera new_camera = *(camera ()); + new_camera.fitBoundingBox(CGAL::qglviewer::Vec(xmin, ymin, zmin), + CGAL::qglviewer::Vec(xmax, ymax, zmax)); camera()->interpolateTo(*new_camera.frame(), 1.); } } diff --git a/Surface_mesher/demo/Surface_mesher/viewer.h b/Surface_mesher/demo/Surface_mesher/viewer.h index 67bb022f73a..8c40a6a6612 100644 --- a/Surface_mesher/demo/Surface_mesher/viewer.h +++ b/Surface_mesher/demo/Surface_mesher/viewer.h @@ -2,11 +2,11 @@ #define _VIEWER_H #include -#include +#include class Surface; -class Viewer : public QGLViewer +class Viewer : public CGAL::QGLViewer { Q_OBJECT public: diff --git a/Surface_mesher/demo/Surface_mesher/volume.cpp b/Surface_mesher/demo/Surface_mesher/volume.cpp index 61e16904d6b..ef025f9ca6a 100644 --- a/Surface_mesher/demo/Surface_mesher/volume.cpp +++ b/Surface_mesher/demo/Surface_mesher/volume.cpp @@ -36,7 +36,7 @@ #include #include -struct Threshold : public CGAL::unary_function { +struct Threshold : public CGAL::cpp98::unary_function { double isovalue; bool is_identity; @@ -54,14 +54,14 @@ struct Threshold : public CGAL::unary_function { }; class Classify_from_isovalue_list : - public CGAL::unary_function + public CGAL::cpp98::unary_function { typedef std::pair Isovalue; typedef std::vector Isovalues; boost::shared_ptr isovalues; bool is_identity; - struct Sort_isovalues : CGAL::binary_function + struct Sort_isovalues : CGAL::cpp98::binary_function { bool operator()(const Isovalue& isoval1, const Isovalue& isoval2) { @@ -110,7 +110,7 @@ public: }; class Generate_surface_identifiers : - public CGAL::binary_function { @@ -137,13 +137,13 @@ public: }; // class Classify_from_isovalue_list : -// public CGAL::unary_function +// public CGAL::cpp98::unary_function // { // typedef std::pair Isovalue; // typedef std::vector Isovalues; // boost::shared_ptr isovalues; -// struct Sort_isovalues : CGAL::binary_function +// struct Sort_isovalues : CGAL::cpp98::binary_function // { // bool operator()(const Isovalue& isoval1, const Isovalue& isoval2) // { @@ -609,8 +609,8 @@ bool Volume::open(const QString& filename) void Volume::finish_open() { m_image.finish_open(); - mw->viewer->camera()->setSceneBoundingBox(qglviewer::Vec(0, 0, 0), - qglviewer::Vec(m_image.xmax(), + mw->viewer->camera()->setSceneBoundingBox(CGAL::qglviewer::Vec(0, 0, 0), + CGAL::qglviewer::Vec(m_image.xmax(), m_image.ymax(), m_image.zmax())); @@ -769,15 +769,15 @@ void Volume::display_marchin_cube() const unsigned int nbt = facets.size() / 9; for(unsigned int i=begin;iitem(value_id))); + m_surface_mc.push_back(Facet_(t,n,values_list->item(value_id))); } nbs_of_mc_triangles[value_id]=m_surface_mc.size(); mc_timer.start(); @@ -791,7 +791,7 @@ void Volume::display_marchin_cube() list_draw_marching_cube_is_valid = false; } CGAL::Bbox_3 bbox(0,0,0,0,0,0); - for(std::vector::const_iterator + for(std::vector::const_iterator it = m_surface_mc.begin(), end = m_surface_mc.end(); it != end; ++it) { @@ -876,7 +876,7 @@ void Volume::display_surface_mesher_result() if(mw->searchSeedsCheckBox->isChecked()) { - typedef std::vector > Seeds; + typedef std::vector > Seeds; Seeds seeds; { std::cerr << "Search seeds...\n"; @@ -905,13 +905,13 @@ void Volume::display_surface_mesher_result() it != end; ++it) { seeds_out << it->first << std::endl; - CGAL::Random_points_on_sphere_3 random_points_on_sphere_3(it->second); + CGAL::Random_points_on_sphere_3 random_points_on_sphere_3(it->second); Oracle::Intersect_3 intersect = oracle.intersect_3_object(); for(int i = 0; i < 20; ++i) { - const Point test = it->first + (*random_points_on_sphere_3++ - CGAL::ORIGIN); + const Point_3 test = it->first + (*random_points_on_sphere_3++ - CGAL::ORIGIN); CGAL::Object o = intersect(surface, Segment_3(it->first, test)); - if (const Point* intersection = CGAL::object_cast(&o)) { + if (const Point_3* intersection = CGAL::object_cast(&o)) { segments_out << "2 " << it->first << " " << *intersection << std::endl; del.insert(*intersection); } @@ -1043,8 +1043,8 @@ void Volume::display_surface_mesher_result() const int index = fit->second; // here "left" means nothing - const Point left_circumcenter = cell->circumcenter(); - const Point right_circumcenter = cell->neighbor(index)->circumcenter(); + const Point_3 left_circumcenter = cell->circumcenter(); + const Point_3 right_circumcenter = cell->neighbor(index)->circumcenter(); const Triangle_3 t = Triangle_3(cell->vertex(del.vertex_triple_index(index, 0))->point(), @@ -1056,13 +1056,13 @@ void Volume::display_surface_mesher_result() n = n / std::sqrt(n*n); if(mw->labellizedRadioButton->isChecked()) { - m_surface.push_back(Facet(t, + m_surface.push_back(Facet_(t, n, values_list->search((std::max)(surface(left_circumcenter), surface(right_circumcenter))))); } else { - m_surface.push_back(Facet(t,n,cell->vertex(del.vertex_triple_index(index, 0))->point().element_index())); + m_surface.push_back(Facet_(t,n,cell->vertex(del.vertex_triple_index(index, 0))->point().element_index())); } } @@ -1072,7 +1072,7 @@ void Volume::display_surface_mesher_result() } CGAL::Bbox_3 bbox(0,0,0,0,0,0); - for(std::vector::const_iterator + for(std::vector::const_iterator it = m_surface.begin(), end = m_surface.end(); it != end; ++it) { @@ -1253,8 +1253,8 @@ void Volume::draw() end = del.finite_edges_end(); eit != end; ++eit) { - const Point p1 = eit->first->vertex(eit->second)->point(); - const Point p2 = eit->first->vertex(eit->third)->point(); + const Point_3 p1 = eit->first->vertex(eit->second)->point(); + const Point_3 p2 = eit->first->vertex(eit->third)->point(); ::glVertex3d(p1.x(),p1.y(),p1.z()); ::glVertex3d(p2.x(),p2.y(),p2.z()); } @@ -1354,9 +1354,9 @@ void Volume::gl_draw_surface() if(c2t3.face_status(facet_cell, facet_index) == C2t3::NOT_IN_COMPLEX) { continue; } - const Point& a = facet_cell->vertex(del.vertex_triple_index(facet_index, 0))->point(); - const Point& b = facet_cell->vertex(del.vertex_triple_index(facet_index, 1))->point(); - const Point& c = facet_cell->vertex(del.vertex_triple_index(facet_index, 2))->point(); + const Point_3& a = facet_cell->vertex(del.vertex_triple_index(facet_index, 0))->point(); + const Point_3& b = facet_cell->vertex(del.vertex_triple_index(facet_index, 1))->point(); + const Point_3& c = facet_cell->vertex(del.vertex_triple_index(facet_index, 2))->point(); Vector n = CGAL::cross_product(b-a,c-a); n = n / std::sqrt(n*n); // unit normal if(m_inverse_normals) { @@ -1443,9 +1443,9 @@ void Volume::gl_draw_surface() else continue; // go to next facet } - const Point& a = opposite_cell->vertex(del.vertex_triple_index(opposite_index, 0))->point(); - const Point& b = opposite_cell->vertex(del.vertex_triple_index(opposite_index, 1))->point(); - const Point& c = opposite_cell->vertex(del.vertex_triple_index(opposite_index, 2))->point(); + const Point_3& a = opposite_cell->vertex(del.vertex_triple_index(opposite_index, 0))->point(); + const Point_3& b = opposite_cell->vertex(del.vertex_triple_index(opposite_index, 1))->point(); + const Point_3& c = opposite_cell->vertex(del.vertex_triple_index(opposite_index, 2))->point(); Vector n = CGAL::cross_product(b-a,c-a); n = n / std::sqrt(n*n); // unit normal if(m_inverse_normals) { @@ -1480,7 +1480,7 @@ void Volume::gl_draw_surface(Iterator begin, Iterator end, const QTreeWidgetItem unsigned int counter = 0; for(Iterator it = begin; it != end; ++it) { - const Facet& f = *it; + const Facet_& f = *it; if(f.get<2>() != i) continue; @@ -1492,9 +1492,9 @@ void Volume::gl_draw_surface(Iterator begin, Iterator end, const QTreeWidgetItem ::glNormal3d(n.x(),n.y(),n.z()); const Triangle_3& t = f.get<0>(); - const Point& a = t[0]; - const Point& b = t[1]; - const Point& c = t[2]; + const Point_3& a = t[0]; + const Point_3& b = t[1]; + const Point_3& c = t[2]; ::glVertex3d(a.x(),a.y(),a.z()); ::glVertex3d(b.x(),b.y(),b.z()); diff --git a/Surface_mesher/demo/Surface_mesher/volume.h b/Surface_mesher/demo/Surface_mesher/volume.h index 408cb6d71ee..7ec0b223e9f 100644 --- a/Surface_mesher/demo/Surface_mesher/volume.h +++ b/Surface_mesher/demo/Surface_mesher/volume.h @@ -43,7 +43,7 @@ struct Kernel : public Kernel1 { }; typedef Kernel::FT FT; -typedef Kernel::Point_3 Point; +typedef Kernel::Point_3 Point_3; typedef Kernel::Sphere_3 Sphere; typedef Kernel::Vector_3 Vector; typedef Kernel::Triangle_3 Triangle_3; @@ -51,9 +51,10 @@ typedef Kernel::Segment_3 Segment_3; // typedef CGAL::Triple Facet; -typedef boost::tuple Facet; +typedef boost::tuple Facet_; -typedef CBinary_image_3 Binary_image; + +typedef CBinary_image_3 Binary_image; class QTreeWidgetItem; @@ -112,7 +113,7 @@ private: bool use_gouraud; bool show_bbox; - std::vector m_surface; + std::vector m_surface; Tr del; // 3D-Delaunay triangulation C2t3 c2t3; // 2D complex in 3D triangulation @@ -132,7 +133,7 @@ private: int sm_total_time; #ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - std::vector m_surface_mc; + std::vector m_surface_mc; MarchingCubes mc ; std::vector nbs_of_mc_triangles; std::vector lists_draw_surface_mc; diff --git a/Surface_mesher/include/CGAL/Implicit_surface_3.h b/Surface_mesher/include/CGAL/Implicit_surface_3.h index fce472af17c..4c7d9eaeb78 100644 --- a/Surface_mesher/include/CGAL/Implicit_surface_3.h +++ b/Surface_mesher/include/CGAL/Implicit_surface_3.h @@ -132,7 +132,7 @@ namespace CGAL { // non documented class template - class Implicit_function_wrapper : public CGAL::unary_function + class Implicit_function_wrapper : public CGAL::cpp98::unary_function { typedef FT (*Implicit_function)(FT, FT, FT); diff --git a/Surface_mesher/include/CGAL/Surface_mesher/Implicit_surface_oracle_3.h b/Surface_mesher/include/CGAL/Surface_mesher/Implicit_surface_oracle_3.h index 2ed6a32971e..f0a1f226b6f 100644 --- a/Surface_mesher/include/CGAL/Surface_mesher/Implicit_surface_oracle_3.h +++ b/Surface_mesher/include/CGAL/Surface_mesher/Implicit_surface_oracle_3.h @@ -106,7 +106,7 @@ namespace CGAL { namespace { template - struct Return_min : CGAL::binary_function + struct Return_min : CGAL::cpp98::binary_function { T operator()(const T& a, const T& b) const { @@ -496,11 +496,6 @@ namespace CGAL { }; // end Implicit_surface_oracle_3 -template -FT approximate_sqrt(const FT x) { - return FT (CGAL_NTS sqrt(CGAL_NTS to_double(x))); -} - } // namespace Surface_mesher } // namespace CGAL diff --git a/Surface_mesher/include/CGAL/Surface_mesher/Sphere_oracle_3.h b/Surface_mesher/include/CGAL/Surface_mesher/Sphere_oracle_3.h index 833383403b0..6904b44accc 100644 --- a/Surface_mesher/include/CGAL/Surface_mesher/Sphere_oracle_3.h +++ b/Surface_mesher/include/CGAL/Surface_mesher/Sphere_oracle_3.h @@ -203,7 +203,7 @@ namespace CGAL { return Object(); } // end private_intersection - struct Lambda_between_0_and_1 : public CGAL::unary_function + struct Lambda_between_0_and_1 : public CGAL::cpp98::unary_function { bool operator()(const FT x) const { @@ -211,7 +211,7 @@ namespace CGAL { } }; - struct Lambda_positive : public CGAL::unary_function + struct Lambda_positive : public CGAL::cpp98::unary_function { bool operator()(const FT x) const { @@ -219,7 +219,7 @@ namespace CGAL { } }; - struct Always_true : public CGAL::unary_function + struct Always_true : public CGAL::cpp98::unary_function { bool operator()(const FT) const { diff --git a/Three/include/CGAL/Three/Scene_item.h b/Three/include/CGAL/Three/Scene_item.h index 76b7ce17f3f..823cb06a489 100644 --- a/Three/include/CGAL/Three/Scene_item.h +++ b/Three/include/CGAL/Three/Scene_item.h @@ -40,9 +40,11 @@ namespace Three { class Viewer_interface; } } +namespace CGAL{ namespace qglviewer { class ManipulatedFrame; } +} class QMenu; class QKeyEvent; @@ -88,7 +90,7 @@ public: NB_OF_PROGRAMS /** Holds the number of different programs in this enum.*/ }; typedef CGAL::Bbox_3 Bbox; - typedef qglviewer::ManipulatedFrame ManipulatedFrame; + typedef CGAL::qglviewer::ManipulatedFrame ManipulatedFrame; //! \brief The default color of a scene_item. //! //! This color is the one that will be displayed if none is specified after its creation. diff --git a/Three/include/CGAL/Three/Viewer_interface.h b/Three/include/CGAL/Three/Viewer_interface.h index f63475a3a1f..fedbd99991b 100644 --- a/Three/include/CGAL/Three/Viewer_interface.h +++ b/Three/include/CGAL/Three/Viewer_interface.h @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include #include @@ -47,7 +47,7 @@ namespace Three{ class Scene_draw_interface; class Scene_item; //! Base class to interact with the viewer from the plugins, the items and the scene. -class VIEWER_EXPORT Viewer_interface : public QGLViewer, public QOpenGLFunctions_2_1 { +class VIEWER_EXPORT Viewer_interface : public CGAL::QGLViewer{ Q_OBJECT @@ -104,7 +104,7 @@ public: //! //! Creates a valid context for OpenGL 2.1. //! \param parent the parent widget. It usually is the MainWindow. - Viewer_interface(QWidget* parent) : QGLViewer(CGAL::Qt::createOpenGLContext(), parent) {} + Viewer_interface(QWidget* parent) : CGAL::QGLViewer(parent) {} virtual ~Viewer_interface() {} //! \brief Sets the scene for the viewer. @@ -123,12 +123,12 @@ public: //! \param frame is the frame that will be moved //! @returns true if it worked. //! @see moveCameraToCoordinates() - static bool readFrame(QString s, qglviewer::Frame& frame); + static bool readFrame(QString s, CGAL::qglviewer::Frame& frame); //! \brief Gives information about a frame. //! @see readFrame //! @see dumpCameraCoordinates() //!@returns a QString containing the position and orientation of a frame. - static QString dumpFrame(const qglviewer::Frame&); + static QString dumpFrame(const CGAL::qglviewer::Frame&); //! \brief The fastDrawing state. //! //! In fast drawing mode, some items will be simplified while the camera is moving @@ -187,8 +187,6 @@ public: //! \brief Used by the items to avoid SEGFAULT. //!@returns true if glVertexAttribDivisor, and glDrawArraysInstanced are found. virtual bool isExtensionFound() = 0; - //!Returns the scene's offset - virtual qglviewer::Vec offset()const = 0; //!\brief Allows to perform picking from the keyboard and mouse //! //! Sets the combination SHIFT+LEFT CLICK to perform a selection on the screen. @@ -251,10 +249,7 @@ public Q_SLOTS: virtual bool moveCameraToCoordinates(QString target, float animation_duration = 0.5f) = 0; public: - //! Is used to know if the openGL context is 4.3 or 2.1. - //! @returns `true` if the context is 4.3. - //! @returns `false` if the context is 2.1. - virtual bool isOpenGL_4_3() const = 0; + //! Gives acces to recent openGL(4.3) features, allowing use of things like //! Geometry Shaders or Depth Textures. //! @returns a pointer to an initialized QOpenGLFunctions_4_3_Compatibility if `isOpenGL_4_3()` is `true` diff --git a/Triangulation_2/doc/Triangulation_2/CGAL/draw_triangulation_2.h b/Triangulation_2/doc/Triangulation_2/CGAL/draw_triangulation_2.h new file mode 100644 index 00000000000..11d13a005a1 --- /dev/null +++ b/Triangulation_2/doc/Triangulation_2/CGAL/draw_triangulation_2.h @@ -0,0 +1,15 @@ +namespace CGAL { + +/*! +\ingroup PkgDrawTriangulation2 + +Open a new window and draw `at2`, a model of the `TriangulationDataStructure_2` concept. The function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. +\tparam T2 a model of the `TriangulationDataStructure_2` concept. +\param at2 the triangulation to draw. + +*/ +template +void draw(const T2& at2); + +} /* namespace CGAL */ + diff --git a/Triangulation_2/doc/Triangulation_2/Concepts/ConstrainedTriangulationTraits_2.h b/Triangulation_2/doc/Triangulation_2/Concepts/ConstrainedTriangulationTraits_2.h index 70518403f11..dd235e31e37 100644 --- a/Triangulation_2/doc/Triangulation_2/Concepts/ConstrainedTriangulationTraits_2.h +++ b/Triangulation_2/doc/Triangulation_2/Concepts/ConstrainedTriangulationTraits_2.h @@ -76,6 +76,15 @@ between `p` and `l`. */ typedef unspecified_type Compute_squared_distance_2; +/*! +A function object whose +`operator()` computes the bounding box of a point. + +`unspecified_type operator()(Point_2 p);` Returns the bounding box of `p`. +The result type is either `Bbox_2` or `Bbox_3` (for projection traits classes). +*/ +typedef unspecified_type Compute_bounding_box_2; + /// @} /// \name Access to Constructor Objects diff --git a/Triangulation_2/doc/Triangulation_2/PackageDescription.txt b/Triangulation_2/doc/Triangulation_2/PackageDescription.txt index a5d99c7a98b..0984fbd61b3 100644 --- a/Triangulation_2/doc/Triangulation_2/PackageDescription.txt +++ b/Triangulation_2/doc/Triangulation_2/PackageDescription.txt @@ -16,6 +16,14 @@ /// \defgroup PkgTriangulation2Miscellaneous Miscellaneous /// \ingroup PkgTriangulation2 +/*! Draw. + \code + #include + \endcode +*/ +/// \defgroup PkgDrawTriangulation2 Draw a Triangulation 2 +/// \ingroup PkgTriangulation2 + /*! \addtogroup PkgTriangulation2 \todo check generated documentation @@ -104,5 +112,8 @@ are described in Chapter \ref PkgTDS2 "2D Triangulation Data Structure". ## Enum ## - \link CGAL::Triangulation_2::Locate_type `CGAL::Triangulation_2::Locate_type` \endlink +### Draw a Triangulation 2 ### +- `CGAL::draw` + */ diff --git a/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt b/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt index eb0daf0d94a..65688e950b0 100644 --- a/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt +++ b/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt @@ -472,6 +472,19 @@ and inserted in the triangulation. Finally points on the convex hull are written to cout. \cgalExample{Triangulation_2/triangulation_prog1.cpp} +\subsection Triangulation2Draw Draw a 2D Triangulation +\anchor ssecDrawT2 + +A 2D triangulation can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given 2D triangulation. The function is blocking, that is the program continues as soon as the user closes the window. + +\cgalExample{Triangulation_2/draw_triangulation_2.cpp} + +This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. + +\cgalFigureBegin{fig_draw_triangulation_2,draw_triangulation_2.png} +Result of the run of the draw_triangulation_2 program. A window shows the 2D triangulation and allows to navigate through the scene. +\cgalFigureEnd + \section Section_2D_Triangulations_Delaunay Delaunay Triangulations \subsection Subsection_2D_Triangulations_Delaunay_Description Description diff --git a/Triangulation_2/doc/Triangulation_2/examples.txt b/Triangulation_2/doc/Triangulation_2/examples.txt index 86a3c4fd016..9bff70297db 100644 --- a/Triangulation_2/doc/Triangulation_2/examples.txt +++ b/Triangulation_2/doc/Triangulation_2/examples.txt @@ -18,4 +18,5 @@ \example Triangulation_2/voronoi.cpp \example Triangulation_2/copy_triangulation_2.cpp \example Triangulation_2/polylines_triangulation.cpp +\example Triangulation_2/draw_triangulation_2.cpp */ diff --git a/Triangulation_2/doc/Triangulation_2/fig/draw_triangulation_2.png b/Triangulation_2/doc/Triangulation_2/fig/draw_triangulation_2.png new file mode 100644 index 00000000000..fee87844199 Binary files /dev/null and b/Triangulation_2/doc/Triangulation_2/fig/draw_triangulation_2.png differ diff --git a/Triangulation_2/examples/Triangulation_2/CMakeLists.txt b/Triangulation_2/examples/Triangulation_2/CMakeLists.txt index 5eb6e369b69..f1a119e58b6 100644 --- a/Triangulation_2/examples/Triangulation_2/CMakeLists.txt +++ b/Triangulation_2/examples/Triangulation_2/CMakeLists.txt @@ -4,9 +4,18 @@ project( Triangulation_2_Examples ) -cmake_minimum_required(VERSION 2.8.10) +cmake_minimum_required(VERSION 3.1) -find_package(CGAL QUIET) +if(NOT POLICY CMP0070 AND POLICY CMP0053) + # Only set CMP0053 to OLD with CMake<3.10, otherwise there is a warning. + cmake_policy(SET CMP0053 OLD) +endif() + +find_package(CGAL COMPONENTS Qt5) + +if(CGAL_Qt5_FOUND) + add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS) +endif() if ( CGAL_FOUND ) @@ -22,6 +31,10 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "${cppfile}" ) endforeach() + if(CGAL_Qt5_FOUND) + target_link_libraries(draw_triangulation_2 PUBLIC CGAL::CGAL_Qt5) + endif() + else() message(STATUS "This program requires the CGAL library, and will not be compiled.") diff --git a/Triangulation_2/examples/Triangulation_2/draw_triangulation_2.cpp b/Triangulation_2/examples/Triangulation_2/draw_triangulation_2.cpp new file mode 100644 index 00000000000..ec8f03b0e3b --- /dev/null +++ b/Triangulation_2/examples/Triangulation_2/draw_triangulation_2.cpp @@ -0,0 +1,21 @@ +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Triangulation_2 Triangulation; +typedef Triangulation::Point Point; + +int main() { + std::ifstream in("data/triangulation_prog1.cin"); + std::istream_iterator begin(in); + std::istream_iterator end; + + Triangulation t; + t.insert(begin, end); + + CGAL::draw(t); + + return EXIT_SUCCESS; +} diff --git a/Triangulation_2/examples/Triangulation_2/info_insert_with_transform_iterator_2.cpp b/Triangulation_2/examples/Triangulation_2/info_insert_with_transform_iterator_2.cpp index cf865ef9ffc..54c73013d0b 100644 --- a/Triangulation_2/examples/Triangulation_2/info_insert_with_transform_iterator_2.cpp +++ b/Triangulation_2/examples/Triangulation_2/info_insert_with_transform_iterator_2.cpp @@ -13,7 +13,7 @@ typedef Delaunay::Point Point; //a functor that returns a std::pair. //the unsigned integer is incremented at each call to //operator() -struct Auto_count : public CGAL::unary_function >{ +struct Auto_count : public CGAL::cpp98::unary_function >{ mutable unsigned i; Auto_count() : i(0){} std::pair operator()(const Point& p) const { diff --git a/Triangulation_2/examples/Triangulation_2/regular.cpp b/Triangulation_2/examples/Triangulation_2/regular.cpp index 2bbfe11e823..4cc0a1857ad 100644 --- a/Triangulation_2/examples/Triangulation_2/regular.cpp +++ b/Triangulation_2/examples/Triangulation_2/regular.cpp @@ -24,5 +24,6 @@ int main() std::cout << rt.number_of_vertices() << std::endl; std::cout << "number of hidden vertices : " ; std::cout << rt.number_of_hidden_vertices() << std::endl; + return 0; } diff --git a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h index a7cb8b2cc69..cd79f2c2914 100644 --- a/Triangulation_2/include/CGAL/Constrained_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Constrained_triangulation_2.h @@ -40,6 +40,10 @@ #include #include + +#include +#include + namespace CGAL { struct No_intersection_tag{}; @@ -413,7 +417,7 @@ insert_constraint(Vertex_handle vaa, Vertex_handle vbb, OutputIterator out) class Less_edge - : public CGAL::binary_function + : public CGAL::cpp98::binary_function { public: Less_edge() {} @@ -1440,11 +1444,72 @@ intersection(const Gt& gt, const typename Gt::Point_2& pc, const typename Gt::Point_2& pd, typename Gt::Point_2& pi, - Exact_predicates_tag) + Exact_predicates_tag, + CGAL::Tag_false /* not a FT is not floating-point */) { return compute_intersection(gt,pa,pb,pc,pd,pi); } +template +inline bool +intersection(const Gt& gt, + const typename Gt::Point_2& pa, + const typename Gt::Point_2& pb, + const typename Gt::Point_2& pc, + const typename Gt::Point_2& pd, + typename Gt::Point_2& pi, + Exact_predicates_tag, + CGAL::Tag_true /* FT is a floating-point type */) +{ + const bool result = compute_intersection(gt,pa,pb,pc,pd,pi); + if(!result) return result; + if(pi == pa || pi == pb || pi == pc || pi == pd) { +#ifdef CGAL_CDT_2_DEBUG_INTERSECTIONS + std::cerr << " CT_2::intersection: intersection is an existing point " + << pi << std::endl; +#endif + return result; + } + + +#ifdef CGAL_CDT_2_INTERSECTION_SNAPPING_ULP_DISTANCE + const int dist = CGAL_CDT_2_INTERSECTION_SNAPPING_ULP_DISTANCE; +#else + const int dist = 4; +#endif + typedef typename Gt::Construct_bbox_2 Construct_bbox_2; + Construct_bbox_2 bbox = gt.construct_bbox_2_object(); + typename boost::result_of::type bb(bbox(pi)); + bb.dilate(dist); + if(do_overlap(bb, bbox(pa))) pi = pa; + if(do_overlap(bb, bbox(pb))) pi = pb; + if(do_overlap(bb, bbox(pc))) pi = pc; + if(do_overlap(bb, bbox(pd))) pi = pd; +#ifdef CGAL_CDT_2_DEBUG_INTERSECTIONS + if(pi == pa || pi == pb || pi == pc || pi == pd) { + std::cerr << " CT_2::intersection: intersection SNAPPED to an existing point " + << pi << std::endl; + } +#endif + return result; +} + +template +inline bool +intersection(const Gt& gt, + const typename Gt::Point_2& pa, + const typename Gt::Point_2& pb, + const typename Gt::Point_2& pc, + const typename Gt::Point_2& pd, + typename Gt::Point_2& pi, + Exact_predicates_tag exact_predicates_tag) +{ + typedef typename Gt::FT FT; + return intersection(gt,pa,pb,pc,pd,pi, + exact_predicates_tag, + Boolean_tag::value>()); +} + template bool diff --git a/Triangulation_2/include/CGAL/Regular_triangulation_2.h b/Triangulation_2/include/CGAL/Regular_triangulation_2.h index 7d29dad74dd..121595ab3c8 100644 --- a/Triangulation_2/include/CGAL/Regular_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Regular_triangulation_2.h @@ -443,7 +443,8 @@ private: template struct Index_to_Bare_point { - const Bare_point& operator()(const std::size_t& i) const + typename boost::result_of::type + operator()(const std::size_t& i) const { return cp(c[i]); } diff --git a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_2.h b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_2.h index 668dca027a3..0a901850a6d 100644 --- a/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_2.h +++ b/Triangulation_2/include/CGAL/boost/graph/graph_traits_Triangulation_2.h @@ -25,7 +25,7 @@ // include this to avoid a VC15 warning #include - +#include #include #include #include @@ -45,114 +45,6 @@ namespace CGAL { namespace detail { -template < class T, class EdgeBase > -class Edge : public EdgeBase { - -public: - typedef typename T::Face_handle Face_handle ; - - Edge() - {} - - Edge(Face_handle fh, int i) - : EdgeBase(fh,i) - {} - - Edge(const EdgeBase& e) - : EdgeBase(e) - {} - - Edge(const Edge& e) - : EdgeBase(e) - {} - - Edge& - operator=(const Edge& e) - { - this->first = e.first; - this->second = e.second; - return *this; - } - - friend std::size_t hash_value(const Edge& e) - { - if (e.first==Face_handle()) return 0; - return hash_value(e.firstneighbor(e.second)? - e.first:e.first->neighbor(e.second)); - } - - bool operator==(const Edge& other) const - { - if((this->first == other.first)&&(this->second == other.second)) return true; - Face_handle fh = this->first->neighbor(this->second); - if(other.first != fh) return false; - int i = fh->index(this->first); - return (other.second == i); - } - - bool operator!=(Edge& other) const - { - return ! (*this == other); - } -}; - -template -class Out_edge_circulator : public Circ -{ -private: - mutable E e; - -public: - - typedef E value_type; - typedef E* pointer; - typedef E& reference; - - Out_edge_circulator() - : Circ() - {} - - Out_edge_circulator(Circ c) - : Circ(c) - {} - - const E& operator*() const - { - E ed = static_cast(this)->operator*(); - e = E(ed.first->neighbor(ed.second), ed.first->neighbor(ed.second)->index(ed.first)); - return e; - } -}; - -template -class In_edge_circulator : public Circ -{ -private: - mutable E e; - -public: - - typedef E value_type; - typedef E* pointer; - typedef E& reference; - - In_edge_circulator() - : Circ() - {} - - In_edge_circulator(Circ c) - : Circ(c) - {} - - const E& operator*() const -{ - typename Circ::value_type ed = static_cast(this)->operator*(); - e = E(ed); - return e; - } -}; - - template struct T2_halfedge_descriptor { @@ -784,14 +676,6 @@ namespace std { #ifndef CGAL_CFG_NO_STD_HASH - template < class T, class EdgeBase> - struct hash > { - std::size_t operator()(const CGAL::detail::Edge& e) const - { - return hash_value(e); - } - }; - template < class Tr> struct hash > { std::size_t operator()(const CGAL::detail::T2_halfedge_descriptor

& e) const diff --git a/Triangulation_2/include/CGAL/draw_triangulation_2.h b/Triangulation_2/include/CGAL/draw_triangulation_2.h new file mode 100644 index 00000000000..a1cfc460fdb --- /dev/null +++ b/Triangulation_2/include/CGAL/draw_triangulation_2.h @@ -0,0 +1,185 @@ +// Copyright(c) 2018 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// Author(s) : Guillaume Damiand + +#ifndef CGAL_DRAW_T2_H +#define CGAL_DRAW_T2_H + +#include +#include + +#ifdef CGAL_USE_BASIC_VIEWER + +#include + +namespace CGAL +{ + +// Default color functor; user can change it to have its own face color +struct DefaultColorFunctorT2 +{ + template + static CGAL::Color run(const T2&, + const typename T2::Finite_faces_iterator fh) + { + CGAL::Random random((unsigned int)(std::size_t)(&*fh)); + return get_random_color(random); + } +}; + +// Viewer class for T2 +template +class SimpleTriangulation2ViewerQt : public Basic_viewer_qt +{ + typedef Basic_viewer_qt Base; + typedef typename T2::Vertex_handle Vertex_const_handle; + typedef typename T2::Finite_edges_iterator Edge_const_handle; + typedef typename T2::Finite_faces_iterator Facet_const_handle; + typedef typename T2::Point Point; + +public: + /// Construct the viewer. + /// @param at2 the t2 to view + /// @param title the title of the window + /// @param anofaces if true, do not draw faces (faces are not computed; this can be + /// usefull for very big object where this time could be long) + SimpleTriangulation2ViewerQt(QWidget* parent, const T2& at2, + const char* title="Basic T2 Viewer", + bool anofaces=false, + const ColorFunctor& fcolor=ColorFunctor()) : + // First draw: vertices; edges, faces; multi-color; no inverse normal + Base(parent, title, true, true, true, false, false), + t2(at2), + m_nofaces(anofaces), + m_fcolor(fcolor) + { + compute_elements(); + } + +protected: + void compute_face(Facet_const_handle fh) + { + CGAL::Color c=m_fcolor.run(t2, fh); + face_begin(c); + + add_point_in_face(fh->vertex(0)->point()); + add_point_in_face(fh->vertex(1)->point()); + add_point_in_face(fh->vertex(2)->point()); + + face_end(); + } + + void compute_edge(Edge_const_handle eh) + { + add_segment(eh->first->vertex(eh->first->cw(eh->second))->point(), + eh->first->vertex(eh->first->ccw(eh->second))->point()); + } + + void compute_vertex(Vertex_const_handle vh) + { add_point(vh->point()); } + + void compute_elements() + { + clear(); + + if (!m_nofaces) + { + for (typename T2::Finite_faces_iterator it=t2.finite_faces_begin(); + it!=t2.finite_faces_end(); ++it) + { compute_face(it); } + } + + for (typename T2::Finite_edges_iterator it=t2.finite_edges_begin(); + it!=t2.finite_edges_end(); ++it) + { compute_edge(it); } + + for (typename T2::Finite_vertices_iterator it=t2.finite_vertices_begin(); + it!=t2.finite_vertices_end(); ++it) + { compute_vertex(it); } + } + + virtual void keyPressEvent(QKeyEvent *e) + { + // Test key pressed: + // const ::Qt::KeyboardModifiers modifiers = e->modifiers(); + // if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) { ... } + + // Call: * compute_elements() if the model changed, followed by + // * redraw() if some viewing parameters changed that implies some + // modifications of the buffers + // (eg. type of normal, color/mono) + // * update() just to update the drawing + + // Call the base method to process others/classicals key + Base::keyPressEvent(e); + } + +protected: + const T2& t2; + bool m_nofaces; + const ColorFunctor& m_fcolor; +}; + +template +void draw(const T2& at2, + const char* title, + bool nofill, + const ColorFunctor& fcolor) +{ +#if defined(CGAL_TEST_SUITE) + bool cgal_test_suite=true; +#else + bool cgal_test_suite=false; +#endif + + if (!cgal_test_suite) + { + int argc=1; + const char* argv[2]={"t2_viewer","\0"}; + QApplication app(argc,const_cast(argv)); + SimpleTriangulation2ViewerQt mainwindow(app.activeWindow(), + at2, + title, + nofill, + fcolor); + mainwindow.show(); + app.exec(); + } +} + +template +void draw(const T2& at2, const char* title, bool nofill) +{ + DefaultColorFunctorT2 c; + draw(at2, title, nofill, c); +} + +template +void draw(const T2& at2, const char* title) +{ draw(at2, title, false); } + +template +void draw(const T2& at2) +{ draw(at2, "Basic T2 Viewer"); } + +} // End namespace CGAL + +#endif // CGAL_USE_BASIC_VIEWER + +#endif // CGAL_DRAW_T2_H diff --git a/Triangulation_2/include/CGAL/internal/Triangulation_2_projection_traits_base_3.h b/Triangulation_2/include/CGAL/internal/Triangulation_2_projection_traits_base_3.h index f0b8b747403..00937af94ef 100644 --- a/Triangulation_2/include/CGAL/internal/Triangulation_2_projection_traits_base_3.h +++ b/Triangulation_2/include/CGAL/internal/Triangulation_2_projection_traits_base_3.h @@ -380,6 +380,7 @@ public: typedef typename K::Construct_circumcenter_3 Construct_circumcenter_2; typedef typename K::Compute_area_3 Compute_area_2; + typedef typename K::Construct_bbox_3 Construct_bbox_2; Less_x_2 less_x_2_object() const @@ -466,6 +467,9 @@ public: {return Compute_area_2();} + Construct_bbox_2 construct_bbox_2_object() const + {return Construct_bbox_2();} + // Special functor, not in the Kernel concept class Projection_to_plan { diff --git a/Triangulation_2/package_info/Triangulation_2/dependencies b/Triangulation_2/package_info/Triangulation_2/dependencies index b28aeef4d20..90dd0267b28 100644 --- a/Triangulation_2/package_info/Triangulation_2/dependencies +++ b/Triangulation_2/package_info/Triangulation_2/dependencies @@ -7,6 +7,7 @@ Distance_2 Distance_3 Filtered_kernel Geomview +GraphicsView Hash_map Homogeneous_kernel Installation diff --git a/Triangulation_3/demo/Triangulation_3/CMakeLists.txt b/Triangulation_3/demo/Triangulation_3/CMakeLists.txt index c0c438c5eb4..d5cd96d8e99 100644 --- a/Triangulation_3/demo/Triangulation_3/CMakeLists.txt +++ b/Triangulation_3/demo/Triangulation_3/CMakeLists.txt @@ -26,7 +26,6 @@ find_package(Qt5 QUIET COMPONENTS OpenGL) if(Qt5_FOUND) add_definitions(-DQT_NO_KEYWORDS) - find_package(QGLViewer) endif(Qt5_FOUND) # Activate concurrency ? (turned OFF by default) @@ -47,9 +46,8 @@ else( CGAL_ACTIVATE_CONCURRENT_TRIANGULATION_3 ) endif( LINK_WITH_TBB ) endif() -if ( CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND ) +if ( CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND ) - include_directories (${QGLVIEWER_INCLUDE_DIR}) include_directories (BEFORE ../../include ./ ) # ui files, created with Qt Designer @@ -68,7 +66,7 @@ if ( CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND ) add_to_cached_list( CGAL_EXECUTABLE_TARGETS T3_demo ) target_link_libraries( T3_demo PRIVATE ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES}) - target_link_libraries( T3_demo PRIVATE Qt5::OpenGL ${QGLVIEWER_LIBRARIES}) + target_link_libraries( T3_demo PRIVATE Qt5::OpenGL) if(TBB_FOUND) CGAL_target_use_TBB(T3_demo) endif() @@ -79,7 +77,7 @@ if ( CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND ) include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake) cgal_add_compilation_test(T3_demo) -else( CGAL_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND ) +else( CGAL_FOUND AND Qt5_FOUND) set(TRIANGULATION_3_MISSING_DEPS "") @@ -91,11 +89,7 @@ else( CGAL_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND ) set(TRIANGULATION_3_MISSING_DEPS "Qt5, ${TRIANGULATION_3_MISSING_DEPS}") endif() - if(NOT QGLVIEWER_FOUND) - set(TRIANGULATION_3_MISSING_DEPS "QGLViewer, ${TRIANGULATION_3_MISSING_DEPS}") - endif() - - + message(STATUS "NOTICE: This demo requires ${TRIANGULATION_3_MISSING_DEPS}and will not be compiled.") -endif( CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND QGLVIEWER_FOUND ) +endif( CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND ) diff --git a/Triangulation_3/demo/Triangulation_3/MainWindow.cpp b/Triangulation_3/demo/Triangulation_3/MainWindow.cpp index 3059b929105..9dd980af04f 100644 --- a/Triangulation_3/demo/Triangulation_3/MainWindow.cpp +++ b/Triangulation_3/demo/Triangulation_3/MainWindow.cpp @@ -81,7 +81,7 @@ void MainWindow::connectActions() // Viewer signals QObject::connect(this, SIGNAL(sceneChanged()), - this->viewer, SLOT(updateGL())); + this->viewer, SLOT(update())); } void MainWindow::closeEvent(QCloseEvent * /*event*/) diff --git a/Triangulation_3/demo/Triangulation_3/Scene.h b/Triangulation_3/demo/Triangulation_3/Scene.h index 2b0c2e0a8e3..45d2e1887d1 100644 --- a/Triangulation_3/demo/Triangulation_3/Scene.h +++ b/Triangulation_3/demo/Triangulation_3/Scene.h @@ -3,7 +3,7 @@ #include "typedefs.h" #include -#include +#include class Scene { @@ -14,7 +14,7 @@ public: ~Scene() { eraseOldData(); } public: - inline void setViewer(QGLViewer* v) { m_viewer = v; } + inline void setViewer(CGAL::QGLViewer* v) { m_viewer = v; } inline void showError(const QString & msg) { if(!m_viewer) m_viewer->displayMessage( msg ); } @@ -35,7 +35,7 @@ private: DT3 m_dt; QList m_vhArray; - QGLViewer* m_viewer; + CGAL::QGLViewer* m_viewer; }; #endif diff --git a/Triangulation_3/demo/Triangulation_3/Viewer.cpp b/Triangulation_3/demo/Triangulation_3/Viewer.cpp index 53d65a38f96..7f8b4fb9fd5 100644 --- a/Triangulation_3/demo/Triangulation_3/Viewer.cpp +++ b/Triangulation_3/demo/Triangulation_3/Viewer.cpp @@ -17,7 +17,6 @@ using namespace std; void Viewer::init() { - initializeOpenGLFunctions(); glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDARBPROC)this->context()->getProcAddress("glDrawArraysInstancedARB"); if(!glDrawArraysInstanced) { @@ -44,7 +43,7 @@ void Viewer::init() /* Scene inits */ setBackgroundColor(::Qt::white); // scene are defined by a sphere of 2.0, camera at the center, i.e. (0, 0, 0) - setSceneCenter( qglviewer::Vec(-0.,-0.,-0.) ); + setSceneCenter( CGAL::qglviewer::Vec(-0.,-0.,-0.) ); setSceneRadius( 2. ); // show text message setTextIsEnabled(true); @@ -89,7 +88,7 @@ void Viewer::init() tr("Cancel insertion in Input-Point mode;
") + tr("Cancel current selection in Select mode") ); setKeyDescription( Qt::Key_Delete, tr("Delete selected vertices in Select mode") ); -#if QGLVIEWER_VERSION >= 0x020500 + setMouseBindingDescription(Qt::NoModifier, Qt::LeftButton, tr("Hold to move new point in Input-Point mode;
") + tr("Hold to move a vertex in Move mode") ); @@ -101,19 +100,7 @@ void Viewer::init() + tr("Click to place a query point in Show-Empty-Sphere mode") ); setMouseBindingDescription(Qt::ControlModifier, Qt::LeftButton, tr("Drag to add vertices to current selection in Select mode") ); -#else - setMouseBindingDescription( Qt::LeftButton, - tr("Hold to move new point in Input-Point mode;
") - + tr("Hold to move a vertex in Move mode") ); - setMouseBindingDescription( Qt::SHIFT + Qt::LeftButton, - tr("Click to insert a vertex in Input-Vertex mode;
") - + tr("Click to insert a point in Input-Point mode;
") - + tr("Click or Drag to select multiple points in Select mode;
") - + tr("Click to place a query point in Find-Nearest-Neighbor mode;
") - + tr("Click to place a query point in Show-Empty-Sphere mode") ); - setMouseBindingDescription( Qt::CTRL + Qt::LeftButton, - tr("Drag to add vertices to current selection in Select mode") ); -#endif + compile_shaders(); are_buffers_initialized = false; } @@ -397,7 +384,7 @@ void Viewer::compute_elements() // normalize v = v / length; // compute the angle: cos theta = v.z/1.0 - GLfloat angle = acos( v.y() ) / M_PI * 180; + GLfloat angle = acos( v.y() ) / CGAL_PI * 180; QMatrix4x4 matrix; matrix.setToIdentity(); // move to "from" point @@ -428,7 +415,7 @@ void Viewer::compute_elements() // normalize v = v / length; // compute the angle: cos theta = v.z/1.0 - GLfloat angle = acos( v.y() ) / M_PI * 180; + GLfloat angle = acos( v.y() ) / CGAL_PI * 180; QMatrix4x4 matrix; matrix.setToIdentity(); // move to "from" point @@ -455,7 +442,7 @@ void Viewer::compute_elements() // normalize v = v / length; // compute the angle: cos theta = v.z/1.0 - GLfloat angle = acos( v.y() ) / M_PI * 180; + GLfloat angle = acos( v.y() ) / CGAL_PI * 180; QMatrix4x4 matrix; matrix.setToIdentity(); // move to "from" point @@ -1105,7 +1092,7 @@ void Viewer::initialize_buffers() are_buffers_initialized = true; } -void Viewer::attrib_buffers(QGLViewer* viewer) +void Viewer::attrib_buffers(CGAL::QGLViewer* viewer) { QMatrix4x4 mvpMatrix; QMatrix4x4 mvMatrix; @@ -1621,10 +1608,13 @@ void Viewer::draw() rendering_program_spheres.bind(); vao[11].bind(); rendering_program_spheres.setUniformValue(colorLocation[1], m_colorTrackball); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if(extension_is_found) glDrawArraysInstanced(GL_TRIANGLES, 0, points_trackBall->size()/3, 1); else glDrawArrays(GL_TRIANGLES, 0, points_trackBall->size()/3); + glDisable(GL_BLEND); vao[11].release(); rendering_program_spheres.release(); } @@ -1800,16 +1790,11 @@ void Viewer::mousePressEvent(QMouseEvent *event) // redraw window { changed(); -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); - -#endif } else // if no point is selected, then regular action (rotation) will be performed - QGLViewer::mousePressEvent(event); + CGAL::QGLViewer::mousePressEvent(event); }//end-if-shift }//end-if-inspt @@ -1822,12 +1807,7 @@ void Viewer::mousePressEvent(QMouseEvent *event) // initialize multiple selection window m_rectSel = QRect( event->pos(), event->pos() ); // redraw window -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); - -#endif break; case Qt::CTRL : // add selection m_isPress = true; @@ -1835,15 +1815,10 @@ void Viewer::mousePressEvent(QMouseEvent *event) // initialize multiple selection window m_rectSel = QRect( event->pos(), event->pos() ); // redraw window -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); - -#endif break; default: // rotate - QGLViewer::mousePressEvent(event); + CGAL::QGLViewer::mousePressEvent(event); break; } }//end-if-select @@ -1857,15 +1832,10 @@ void Viewer::mousePressEvent(QMouseEvent *event) select( event->pos() ); if( m_isMoving ) // redraw window { changed(); -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); - -#endif } else // if no point is selected, then regular action (rotation) will be performed - QGLViewer::mousePressEvent(event); + CGAL::QGLViewer::mousePressEvent(event); }//end-if-move else if( m_curMode == FINDNB @@ -1886,7 +1856,7 @@ void Viewer::mousePressEvent(QMouseEvent *event) }//end-if-emptyS else - QGLViewer::mousePressEvent(event); + CGAL::QGLViewer::mousePressEvent(event); } @@ -1900,12 +1870,7 @@ void Viewer::mouseMoveEvent(QMouseEvent *event) computeConflict( m_newPt ); // redraw changed(); -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); - -#endif }//end-if-compute }//end-if-inspt @@ -1943,7 +1908,7 @@ void Viewer::mouseMoveEvent(QMouseEvent *event) }//end-if-move else - QGLViewer::mouseMoveEvent(event); + CGAL::QGLViewer::mouseMoveEvent(event); } void Viewer::mouseReleaseEvent(QMouseEvent *event) @@ -1958,12 +1923,7 @@ void Viewer::mouseReleaseEvent(QMouseEvent *event) // redraw changed(); -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); - -#endif }//end-if-ins /* INS_PT mode - Shift+Left: compute and insert a point */ @@ -1979,12 +1939,8 @@ void Viewer::mouseReleaseEvent(QMouseEvent *event) // redraw changed(); -#if QGLVIEWER_VERSION >= 0x020700 - update(); -#else - updateGL(); + update(); -#endif }//end-if-inspt /* INS_PT mode - Left: compute and insert a point */ @@ -1999,12 +1955,7 @@ void Viewer::mouseReleaseEvent(QMouseEvent *event) // redraw changed(); -#if QGLVIEWER_VERSION >= 0x020700 - update(); -#else - updateGL(); - -#endif + update(); }//end-if-inspt /* SEL mode - Left: terminate multiple point selection */ @@ -2047,12 +1998,7 @@ void Viewer::mouseReleaseEvent(QMouseEvent *event) // update display to show changed(); -#if QGLVIEWER_VERSION >= 0x020700 - update(); -#else - updateGL(); - -#endif + update(); }//end-if-select /* MOVE mode - Left: terminate point moving */ @@ -2080,13 +2026,7 @@ void Viewer::mouseReleaseEvent(QMouseEvent *event) // redraw changed(); -#if QGLVIEWER_VERSION >= 0x020700 - update(); -#else - updateGL(); - -#endif - + update(); }//end-if-move /* FindNb mode - Shift+Left: find the nearest neighbor of the point */ @@ -2100,12 +2040,7 @@ void Viewer::mouseReleaseEvent(QMouseEvent *event) // redraw changed(); -#if QGLVIEWER_VERSION >= 0x020700 - update(); -#else - updateGL(); - -#endif + update(); }//end-if-findnb /* EmptySphere mode - Shift+Left: show the empty sphere of the cell */ @@ -2131,16 +2066,11 @@ void Viewer::mouseReleaseEvent(QMouseEvent *event) }//end-if-compute // redraw changed(); -#if QGLVIEWER_VERSION >= 0x020700 - update(); -#else - updateGL(); - -#endif + update(); }//end-if-emptysphere else - QGLViewer::mouseReleaseEvent(event); + CGAL::QGLViewer::mouseReleaseEvent(event); } @@ -2161,12 +2091,7 @@ void Viewer::wheelEvent(QWheelEvent *event) // redraw changed(); -#if QGLVIEWER_VERSION >= 0x020700 - update(); -#else - updateGL(); - -#endif + update(); }//end-if-insv else if( m_curMode == INSERT_PT && modifiers == Qt::SHIFT ) { @@ -2188,12 +2113,7 @@ void Viewer::wheelEvent(QWheelEvent *event) // redraw changed(); -#if QGLVIEWER_VERSION >= 0x020700 - update(); -#else - updateGL(); - -#endif + update(); }//end-if-inspt // resize the trackball when moving a point @@ -2224,16 +2144,11 @@ void Viewer::wheelEvent(QWheelEvent *event) // redraw changed(); -#if QGLVIEWER_VERSION >= 0x020700 - update(); -#else - updateGL(); - -#endif + update(); }//end-if-move else - QGLViewer::wheelEvent(event); + CGAL::QGLViewer::wheelEvent(event); } void Viewer::keyPressEvent(QKeyEvent *event) @@ -2266,12 +2181,7 @@ void Viewer::keyPressEvent(QKeyEvent *event) // redraw changed(); -#if QGLVIEWER_VERSION >= 0x020700 - update(); -#else - updateGL(); - -#endif + update(); }//end-if-insVertex /* Cancel the newly inserted point and its conflict region */ @@ -2284,12 +2194,7 @@ void Viewer::keyPressEvent(QKeyEvent *event) // redraw changed(); -#if QGLVIEWER_VERSION >= 0x020700 - update(); -#else - updateGL(); - -#endif + update(); }//end-if-escapeIns /* Delete selected points */ @@ -2307,12 +2212,7 @@ void Viewer::keyPressEvent(QKeyEvent *event) // redraw changed(); -#if QGLVIEWER_VERSION >= 0x020700 - update(); -#else - updateGL(); - -#endif + update(); }//end-if-del /* Cancel the selection */ @@ -2326,12 +2226,7 @@ void Viewer::keyPressEvent(QKeyEvent *event) // redraw changed(); -#if QGLVIEWER_VERSION >= 0x020700 - update(); -#else - updateGL(); - -#endif + update(); }//end-if-escapeSel @@ -2341,26 +2236,16 @@ void Viewer::keyPressEvent(QKeyEvent *event) m_showTrackball = !m_showTrackball; // redraw changed(); -#if QGLVIEWER_VERSION >= 0x020700 - update(); -#else - updateGL(); - -#endif + update(); }//end-if-showBall else - QGLViewer::keyPressEvent(event); + CGAL::QGLViewer::keyPressEvent(event); // redraw changed(); -#if QGLVIEWER_VERSION >= 0x020700 - update(); -#else - updateGL(); - -#endif + update(); } /*************************************************************/ @@ -2442,12 +2327,7 @@ void Viewer::toggleIncremental(bool on) { // redraw changed(); -#if QGLVIEWER_VERSION >= 0x020700 - update(); -#else - updateGL(); - -#endif + update(); } void Viewer::stopIncremental() { @@ -2472,12 +2352,7 @@ void Viewer::stopIncremental() { // redraw changed(); -#if QGLVIEWER_VERSION >= 0x020700 - update(); -#else - updateGL(); - -#endif + update(); } void Viewer::incremental_insert() { @@ -2537,12 +2412,7 @@ void Viewer::incremental_insert() { // redraw changed(); -#if QGLVIEWER_VERSION >= 0x020700 - update(); -#else - updateGL(); - -#endif + update(); } @@ -2570,8 +2440,8 @@ void Viewer::draw_cylinder(float R, int prec, std::vector *vertices, std: - P = rings*M_PI/180.0; - T = t*M_PI/180.0; + P = rings*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[1] = sin(P) * cos(T) ; z[1] = sin(P) * sin(T) ; y[1] = cos(P); @@ -2585,8 +2455,8 @@ void Viewer::draw_cylinder(float R, int prec, std::vector *vertices, std: normals->push_back(z[1]); // - P = rings*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = rings*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[2] = sin(P) * cos(T) ; z[2] = sin(P) * sin(T) ; y[2] = cos(P); @@ -2604,8 +2474,8 @@ void Viewer::draw_cylinder(float R, int prec, std::vector *vertices, std: for(int t=0; t<360; t+=sectors) { //A - P = p*M_PI/180.0; - T = t*M_PI/180.0; + P = p*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[0] = sin(P) * cos(T) ; z[0] = sin(P) * sin(T) ; y[0] = cos(P); @@ -2620,8 +2490,8 @@ void Viewer::draw_cylinder(float R, int prec, std::vector *vertices, std: normals->push_back(z[0]); //B - P = (p+rings)*M_PI/180.0; - T = t*M_PI/180.0; + P = (p+rings)*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[1] = sin(P) * cos(T) ; z[1] = sin(P) * sin(T) ; y[1] = cos(P); @@ -2635,8 +2505,8 @@ void Viewer::draw_cylinder(float R, int prec, std::vector *vertices, std: normals->push_back(z[1]); //C - P = p*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = p*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[2] = sin(P) * cos(T) ; z[2] = sin(P) * sin(T) ; y[2] = cos(P); @@ -2649,8 +2519,8 @@ void Viewer::draw_cylinder(float R, int prec, std::vector *vertices, std: normals->push_back(y[2]); normals->push_back(z[2]); //D - P = (p+rings)*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = (p+rings)*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[3] = sin(P) * cos(T) ; z[3] = sin(P) * sin(T) ; y[3] = cos(P); @@ -2691,7 +2561,7 @@ void Viewer::draw_cylinder(float R, int prec, std::vector *vertices, std: { //point A1 - float D = d*M_PI/180.0; + float D = d*CGAL_PI/180.0; vertices->push_back(R * sin(D)); vertices->push_back(0); vertices->push_back(R * cos(D)); @@ -2710,7 +2580,7 @@ void Viewer::draw_cylinder(float R, int prec, std::vector *vertices, std: normals->push_back(cos(D)); //point C1 - D = (d+360/prec)*M_PI/180.0; + D = (d+360/prec)*CGAL_PI/180.0; vertices->push_back(R * sin(D)); vertices->push_back(1); vertices->push_back(R * cos(D)); @@ -2720,7 +2590,7 @@ void Viewer::draw_cylinder(float R, int prec, std::vector *vertices, std: normals->push_back(cos(D)); //point A2 - D = (d+360/prec)*M_PI/180.0; + D = (d+360/prec)*CGAL_PI/180.0; vertices->push_back(R * sin(D)); vertices->push_back(1); vertices->push_back(R * cos(D)); @@ -2739,7 +2609,7 @@ void Viewer::draw_cylinder(float R, int prec, std::vector *vertices, std: normals->push_back(cos(D)); //point C2 - D = d*M_PI/180.0; + D = d*CGAL_PI/180.0; vertices->push_back(R * sin(D)); vertices->push_back(0); vertices->push_back(R * cos(D)); @@ -2765,8 +2635,8 @@ void Viewer::draw_cylinder(float R, int prec, std::vector *vertices, std: - P = rings*M_PI/180.0; - T = t*M_PI/180.0; + P = rings*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[1] = sin(P) * cos(T) ; z[1] = sin(P) * sin(T) ; y[1] = cos(P); @@ -2780,8 +2650,8 @@ void Viewer::draw_cylinder(float R, int prec, std::vector *vertices, std: normals->push_back(z[1]); // - P = rings*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = rings*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[2] = sin(P) * cos(T) ; z[2] = sin(P) * sin(T) ; y[2] = cos(P); @@ -2799,8 +2669,8 @@ void Viewer::draw_cylinder(float R, int prec, std::vector *vertices, std: for(int t=0; t<360; t+=sectors) { //A - P = p*M_PI/180.0; - T = t*M_PI/180.0; + P = p*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[0] = sin(P) * cos(T) ; z[0] = sin(P) * sin(T) ; y[0] = cos(P); @@ -2815,8 +2685,8 @@ void Viewer::draw_cylinder(float R, int prec, std::vector *vertices, std: normals->push_back(z[0]); //B - P = (p+rings)*M_PI/180.0; - T = t*M_PI/180.0; + P = (p+rings)*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[1] = sin(P) * cos(T) ; z[1] = sin(P) * sin(T) ; y[1] = cos(P); @@ -2830,8 +2700,8 @@ void Viewer::draw_cylinder(float R, int prec, std::vector *vertices, std: normals->push_back(z[1]); //C - P = p*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = p*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[2] = sin(P) * cos(T) ; z[2] = sin(P) * sin(T) ; y[2] = cos(P); @@ -2844,8 +2714,8 @@ void Viewer::draw_cylinder(float R, int prec, std::vector *vertices, std: normals->push_back(y[2]); normals->push_back(z[2]); //D - P = (p+rings)*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = (p+rings)*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[3] = sin(P) * cos(T) ; z[3] = sin(P) * sin(T) ; y[3] = cos(P); @@ -2907,8 +2777,8 @@ void Viewer::draw_sphere(float R, int prec, std::vector *vertices, std::v - P = rings*M_PI/180.0; - T = t*M_PI/180.0; + P = rings*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[1] = sin(P) * cos(T) ; y[1] = sin(P) * sin(T) ; z[1] = cos(P); @@ -2922,8 +2792,8 @@ void Viewer::draw_sphere(float R, int prec, std::vector *vertices, std::v normals->push_back(z[1]); // - P = rings*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = rings*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[2] = sin(P) * cos(T) ; y[2] = sin(P) * sin(T) ; z[2] = cos(P); @@ -2942,8 +2812,8 @@ void Viewer::draw_sphere(float R, int prec, std::vector *vertices, std::v for(int t=0; t<360; t+=sectors) { //A - P = p*M_PI/180.0; - T = t*M_PI/180.0; + P = p*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[0] = sin(P) * cos(T) ; y[0] = sin(P) * sin(T) ; z[0] = cos(P); @@ -2958,8 +2828,8 @@ void Viewer::draw_sphere(float R, int prec, std::vector *vertices, std::v normals->push_back(z[0]); //B - P = (p+rings)*M_PI/180.0; - T = t*M_PI/180.0; + P = (p+rings)*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[1] = sin(P) * cos(T) ; y[1] = sin(P) * sin(T) ; z[1] = cos(P); @@ -2973,8 +2843,8 @@ void Viewer::draw_sphere(float R, int prec, std::vector *vertices, std::v normals->push_back(z[1]); //C - P = p*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = p*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[2] = sin(P) * cos(T) ; y[2] = sin(P) * sin(T) ; z[2] = cos(P); @@ -2987,8 +2857,8 @@ void Viewer::draw_sphere(float R, int prec, std::vector *vertices, std::v normals->push_back(y[2]); normals->push_back(z[2]); //D - P = (p+rings)*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = (p+rings)*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[3] = sin(P) * cos(T) ; y[3] = sin(P) * sin(T) ; z[3] = cos(P); @@ -3037,8 +2907,8 @@ void Viewer::draw_sphere(float R, int prec, std::vector *vertices, std::v normals->push_back(-1); - P = (180-rings)*M_PI/180.0; - T = t*M_PI/180.0; + P = (180-rings)*CGAL_PI/180.0; + T = t*CGAL_PI/180.0; x[1] = sin(P) * cos(T) ; y[1] = sin(P) * sin(T) ; z[1] = cos(P); @@ -3052,8 +2922,8 @@ void Viewer::draw_sphere(float R, int prec, std::vector *vertices, std::v normals->push_back(z[1]); - P = (180-rings)*M_PI/180.0; - T = (t+sectors)*M_PI/180.0; + P = (180-rings)*CGAL_PI/180.0; + T = (t+sectors)*CGAL_PI/180.0; x[2] = sin(P) * cos(T) ; y[2] = sin(P) * sin(T) ; z[2] = cos(P); diff --git a/Triangulation_3/demo/Triangulation_3/Viewer.h b/Triangulation_3/demo/Triangulation_3/Viewer.h index d4c6302ed85..178132d8077 100644 --- a/Triangulation_3/demo/Triangulation_3/Viewer.h +++ b/Triangulation_3/demo/Triangulation_3/Viewer.h @@ -3,7 +3,7 @@ #include "Scene.h" #include -#include +#include #include #include #include @@ -15,17 +15,17 @@ #include #include #include -using namespace qglviewer; +using namespace CGAL::qglviewer; class MainWindow; -class Viewer : public QGLViewer, QOpenGLFunctions_2_1 { +class Viewer : public CGAL::QGLViewer{ Q_OBJECT public: Viewer(QWidget* parent) - : QGLViewer(CGAL::Qt::createOpenGLContext(),parent) + : CGAL::QGLViewer(parent) , m_showAxis(false) , m_showVertex(true) , m_showDEdge(true) @@ -100,13 +100,7 @@ public: m_isMoving = false; m_hasEmptyS = false; m_nearestNb = NULL; -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); - -#endif - } // set selectBuffer size (if necessary) @@ -202,52 +196,22 @@ public Q_SLOTS: // show options inline void toggleShowAxis(bool flag) { m_showAxis = flag; -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); - -#endif } inline void toggleShowVertex(bool flag) { m_showVertex = flag; - #if QGLVIEWER_VERSION >= 0x020700 update(); - #else - updateGL(); - - #endif } inline void toggleShowDEdge(bool flag) { m_showDEdge = flag; - #if QGLVIEWER_VERSION >= 0x020700 update(); - #else - updateGL(); - - #endif } inline void toggleShowVEdge(bool flag) { m_showVEdge = flag; - #if QGLVIEWER_VERSION >= 0x020700 update(); - #else - updateGL(); - - #endif } inline void toggleShowFacet(bool flag) { m_showFacet = flag; - #if QGLVIEWER_VERSION >= 0x020700 update(); - #else - updateGL(); - - #endif } inline void toggleFlat(bool flag) { m_isFlat = flag; - #if QGLVIEWER_VERSION >= 0x020700 update(); - #else - updateGL(); - - #endif } // set preferences @@ -275,18 +239,13 @@ public Q_SLOTS: m_iStep = m_pDlgPrefer->m_iStep*40; m_colorEmptySphere = m_pDlgPrefer->m_colorEmptySphere; // redraw -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); - -#endif } Q_SIGNALS: void stopIncAnimation(); -// overloading QGLViewer virtual functions +// overloading CGAL::QGLViewer virtual functions protected: // initialize Viewer OpenGL context // Note: the default implement is empty and this is overloading. @@ -448,7 +407,7 @@ private: PFNGLVERTEXATTRIBDIVISORARBPROC glVertexAttribDivisor; void initialize_buffers(); void compute_elements(); - void attrib_buffers(QGLViewer*); + void attrib_buffers(CGAL::QGLViewer*); void compile_shaders(); void draw_cylinder(float R, int prec, std::vector *vertices, std::vector *normals); void draw_sphere(float R, int prec, std::vector *vertices, std::vector *normals); diff --git a/Triangulation_3/doc/Triangulation_3/CGAL/Delaunay_triangulation_3.h b/Triangulation_3/doc/Triangulation_3/CGAL/Delaunay_triangulation_3.h index 6ccff4252fc..5b4449f1ecf 100644 --- a/Triangulation_3/doc/Triangulation_3/CGAL/Delaunay_triangulation_3.h +++ b/Triangulation_3/doc/Triangulation_3/CGAL/Delaunay_triangulation_3.h @@ -162,7 +162,7 @@ Delaunay_triangulation_3 (InputIterator first, InputIterator last, /// @{ /*! -Inserts point `p` in the triangulation and returns the corresponding +Inserts the point `p` in the triangulation and returns the corresponding vertex. Similar to the insertion in a triangulation, but ensures in addition the empty sphere property of all the created faces. The optional argument `start` is used as a starting place for the search. @@ -185,7 +185,7 @@ Vertex_handle insert(const Point & p, Vertex_handle hint, bool *could_lock_zone = NULL); /*! -Inserts point `p` in the triangulation and returns the corresponding +Inserts the point `p` in the triangulation and returns the corresponding vertex. Similar to the above `insert()` function, but takes as additional parameter the return values of a previous location query. See description of `Triangulation_3::locate()`. @@ -397,17 +397,14 @@ specifying where to start the search. \pre `c` is a cell of `dt`. */ -Vertex_handle nearest_vertex(Point p, -Cell_handle c = Cell_handle()); +Vertex_handle nearest_vertex(const Point& p, + Cell_handle c = Cell_handle()); /*! -Returns the vertex of the cell `c` that is -nearest to \f$ p\f$. - +Returns the vertex of the cell `c` that is nearest to \f$ p\f$. */ -Vertex_handle nearest_vertex_in_cell(Point p, -Cell_handle c); - +Vertex_handle nearest_vertex_in_cell(const Point& p, + Cell_handle c); /// @} @@ -447,9 +444,9 @@ Returns the pair composed of the resulting output iterators. template std::pair -find_conflicts(Point p, Cell_handle c, -OutputIteratorBoundaryFacets bfit, -OutputIteratorCells cit, bool *could_lock_zone = NULL); +find_conflicts(const Point& p, Cell_handle c, + OutputIteratorBoundaryFacets bfit, + OutputIteratorCells cit, bool *could_lock_zone = NULL); /*! Same as the other `find_conflicts()` function, except that it also @@ -479,24 +476,23 @@ Returns the `Triple` composed of the resulting output iterators. */ template + class OutputIteratorCells, + class OutputIteratorInternalFacets> Triple -find_conflicts(Point p, Cell_handle c, -OutputIteratorBoundaryFacets bfit, -OutputIteratorCells cit, -OutputIteratorInternalFacets ifit, -bool *could_lock_zone = NULL); + OutputIteratorCells, + OutputIteratorInternalFacets> +find_conflicts(const Point& p, Cell_handle c, + OutputIteratorBoundaryFacets bfit, + OutputIteratorCells cit, + OutputIteratorInternalFacets ifit, + bool *could_lock_zone = NULL); /*! \deprecated This function is renamed `vertices_on_conflict_zone_boundary` since CGAL-3.8. */ template OutputIterator -vertices_in_conflict(Point p, Cell_handle c, -OutputIterator res); +vertices_in_conflict(const Point& p, Cell_handle c, OutputIterator res); /*! Similar to `find_conflicts()`, but reports the vertices which are on the @@ -507,9 +503,7 @@ Returns the resulting output iterator. */ template OutputIterator -vertices_on_conflict_zone_boundary(Point p, Cell_handle c, -OutputIterator res); - +vertices_on_conflict_zone_boundary(const Point& p, Cell_handle c, OutputIterator res); /// @} diff --git a/Triangulation_3/doc/Triangulation_3/CGAL/Regular_triangulation_3.h b/Triangulation_3/doc/Triangulation_3/CGAL/Regular_triangulation_3.h index 6591182c7df..22ad57a0db6 100644 --- a/Triangulation_3/doc/Triangulation_3/CGAL/Regular_triangulation_3.h +++ b/Triangulation_3/doc/Triangulation_3/CGAL/Regular_triangulation_3.h @@ -64,13 +64,12 @@ public: /// @{ /*! -The type for points -`p` of weighted points \f$ {p}^{(w)}=(p,w_p)\f$ +The type for points `p` of weighted points \f$ {p}^{(w)}=(p,w_p)\f$ */ typedef Traits::Point_3 Bare_point; /*! - +The type for weighted points */ typedef Traits::Weighted_point_3 Weighted_point; @@ -126,7 +125,7 @@ The following methods, which already exist in `Triangulation_3`, are overloaded /// @{ /*! -Inserts weighted point `p` in the triangulation. The optional +Inserts the weighted point `p` in the triangulation. The optional argument `start` is used as a starting place for the search. If this insertion creates a vertex, this vertex is returned. @@ -160,7 +159,7 @@ Same as above but uses `hint` as a starting place for the search. Vertex_handle insert(const Weighted_point & p, Vertex_handle hint, bool *could_lock_zone = NULL); /*! -Inserts weighted point `p` in the triangulation and returns the corresponding +Inserts the weighted point `p` in the triangulation and returns the corresponding vertex. Similar to the above `insert()` function, but takes as additional parameter the return values of a previous location query. See description of `Triangulation_3::locate()`. @@ -229,16 +228,18 @@ of `p` and is stored in the new cell which contains it. \pre `rt`.`dimension()` \f$ \geq2\f$, the set of cells (resp. facets in dimension 2) is connected, not empty, its boundary is connected, and `p` lies inside the hole, which is star-shaped wrt `p`. */ template -Vertex_handle insert_in_hole(Weighted_point p, CellIt cell_begin, CellIt cell_end, -Cell_handle begin, int i); +Vertex_handle insert_in_hole(const Weighted_point& p, + CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i); /*! Same as above, except that `newv` will be used as the new vertex, which must have been allocated previously with, e.g.\ `create_vertex`. */ template -Vertex_handle insert_in_hole(Weighted_point p, CellIt cell_begin, CellIt cell_end, -Cell_handle begin, int i, Vertex_handle newv); +Vertex_handle insert_in_hole(const Weighted_point& p, + CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i, Vertex_handle newv); /// @} @@ -406,7 +407,7 @@ with respect to the power distance. This means that the power of the query point `p` with respect to the weighted point in the returned vertex is smaller than the power of `p` with respect to the weighted point -in any other vertex. Ties are broken arbitrarily. +for any other vertex. Ties are broken arbitrarily. The default constructed handle is returned if the triangulation is empty. The optional argument `c` is a hint @@ -414,8 +415,8 @@ specifying where to start the search. \pre `c` is a cell of `rt`. */ -Vertex_handle nearest_power_vertex(Weighted_point p, -Cell_handle c = Cell_handle()); +Vertex_handle nearest_power_vertex(const Bare_point& p, + Cell_handle c = Cell_handle()); /*! Returns the vertex of the cell `c` @@ -423,8 +424,8 @@ that is nearest to \f$ p\f$ with respect to the power distance. */ -Vertex_handle nearest_power_vertex_in_cell(Weighted_point p, -Cell_handle c); +Vertex_handle nearest_power_vertex_in_cell(const Bare_point& p, + Cell_handle c); /// @} @@ -485,8 +486,7 @@ bool *the_facet_is_in_its_cz = NULL); */ template OutputIterator -vertices_in_conflict(Weighted_point p, Cell_handle c, -OutputIterator res); +vertices_in_conflict(const Weighted_point& p, Cell_handle c, OutputIterator res); /*! Similar to `find_conflicts()`, but reports the vertices which are on the @@ -497,8 +497,7 @@ Returns the resulting output iterator. */ template OutputIterator -vertices_on_conflict_zone_boundary(Weighted_point p, Cell_handle c, -OutputIterator res); +vertices_on_conflict_zone_boundary(const Weighted_point& p, Cell_handle c, OutputIterator res); /*! Similar to `find_conflicts()`, but reports the vertices which are in @@ -511,7 +510,7 @@ Returns the resulting output iterator. */ template OutputIterator -vertices_inside_conflict_zone(Weighted_point p, Cell_handle c, +vertices_inside_conflict_zone(const Weighted_point& p, Cell_handle c, OutputIterator res); diff --git a/Triangulation_3/doc/Triangulation_3/CGAL/Triangulation_3.h b/Triangulation_3/doc/Triangulation_3/CGAL/Triangulation_3.h index 1c8683e53ba..3bd0dfbe653 100644 --- a/Triangulation_3/doc/Triangulation_3/CGAL/Triangulation_3.h +++ b/Triangulation_3/doc/Triangulation_3/CGAL/Triangulation_3.h @@ -862,7 +862,7 @@ void flip_flippable(Cell_handle c, int i); /// @{ /*! -Inserts point `p` in the triangulation and returns the corresponding +Inserts the point `p` in the triangulation and returns the corresponding vertex. If point `p` coincides with an already existing vertex, this @@ -896,7 +896,7 @@ Same as above but uses `hint` as the starting place for the search. Vertex_handle insert(const Point & p, Vertex_handle hint); /*! -Inserts point `p` in the triangulation and returns the corresponding +Inserts the point `p` in the triangulation and returns the corresponding vertex. Similar to the above `insert()` function, but takes as additional parameter the return values of a previous location query. See description of locate() above. @@ -926,14 +926,14 @@ valid triangulation when they are applied on a valid triangulation. // @{ /*! -Inserts point `p` in cell `c`. Cell `c` is split into 4 +Inserts the point `p` in the cell `c`. The cell `c` is split into 4 tetrahedra. \pre `t.dimension() == 3` and `p` lies strictly inside cell `c`. */ Vertex_handle insert_in_cell(const Point & p, Cell_handle c); /*! -Inserts point `p` in facet `f`. In dimension 3, the 2 +Inserts the point `p` in the facet `f`. In dimension 3, the 2 neighboring cells are split into 3 tetrahedra; in dimension 2, the facet is split into 3 triangles. \pre `t.dimension()` \f$ \geq2\f$ and `p` lies strictly inside face `f`. @@ -941,14 +941,14 @@ is split into 3 triangles. Vertex_handle insert_in_facet(const Point & p, const Facet & f); /*! -As above, insertion in facet `(c,i)`. +As above, insertion in the facet `(c,i)`. \pre As above and \f$ i \in\{0,1,2,3\}\f$ in dimension 3, \f$ i = 3\f$ in dimension 2. */ Vertex_handle insert_in_facet(const Point & p, Cell_handle c, int i); /*! -Inserts `p` in edge `e`. In dimension 3, +Inserts `p` in the edge `e`. In dimension 3, all the cells having this edge are split into 2 tetrahedra; in dimension 2, the 2 neighboring facets are split into 2 triangles; in dimension 1, the edge is split into 2 edges. @@ -957,10 +957,10 @@ dimension 1, the edge is split into 2 edges. Vertex_handle insert_in_edge(const Point & p, const Edge & e); /*! -As above, inserts `p` in edge \f$ (i, j)\f$ of `c`. +As above, inserts `p` in the edge \f$ (i, j)\f$ of `c`. \pre As above and \f$ i\neq j\f$. Moreover \f$ i,j \in\{0,1,2,3\}\f$ in dimension 3, \f$ i,j \in\{0,1,2\}\f$ in dimension 2, \f$ i,j \in\{0,1\}\f$ in dimension 1. */ -Vertex_handle insert_in_edge(Point p, Cell_handle c, int i, int j); +Vertex_handle insert_in_edge(const Point& p, Cell_handle c, int i, int j); /*! The cell `c` must be an infinite cell containing `p`. @@ -1011,16 +1011,16 @@ This operation is equivalent to calling \pre `t.dimension()` \f$ \geq2\f$, the set of cells (resp. facets in dimension 2) is connected, its boundary is connected, and `p` lies inside the hole, which is star-shaped wrt `p`. */ template -Vertex_handle insert_in_hole(Point p, CellIt cell_begin, CellIt cell_end, -Cell_handle begin, int i); +Vertex_handle insert_in_hole(const Point& p, CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i); /*! Same as above, except that `newv` will be used as the new vertex, which must have been allocated previously with e.g.\ `create_vertex`. */ template -Vertex_handle insert_in_hole(Point p, CellIt cell_begin, CellIt cell_end, -Cell_handle begin, int i, Vertex_handle newv); +Vertex_handle insert_in_hole(const Point& p, CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i, Vertex_handle newv); /// @} diff --git a/Triangulation_3/doc/Triangulation_3/CGAL/draw_triangulation_3.h b/Triangulation_3/doc/Triangulation_3/CGAL/draw_triangulation_3.h new file mode 100644 index 00000000000..b7704903210 --- /dev/null +++ b/Triangulation_3/doc/Triangulation_3/CGAL/draw_triangulation_3.h @@ -0,0 +1,15 @@ +namespace CGAL { + +/*! +\ingroup PkgDrawTriangulation3 + +Open a new window and draw `at3`, a model of the `TriangulationDataStructure_3` concept. The function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. +\tparam T3 a model of the `TriangulationDataStructure_3` concept. +\param at3 the triangulation to draw. + +*/ +template +void draw(const T3& at3); + +} /* namespace CGAL */ + diff --git a/Triangulation_3/doc/Triangulation_3/PackageDescription.txt b/Triangulation_3/doc/Triangulation_3/PackageDescription.txt index 5af6493c805..11a1a0fe6a6 100644 --- a/Triangulation_3/doc/Triangulation_3/PackageDescription.txt +++ b/Triangulation_3/doc/Triangulation_3/PackageDescription.txt @@ -13,6 +13,13 @@ /// \defgroup PkgTriangulation3VertexCellClasses Vertex and Cell Classes /// \ingroup PkgTriangulation3 +/*! Draw. + \code + #include + \endcode +*/ +/// \defgroup PkgDrawTriangulation3 Draw a Triangulation 3 +/// \ingroup PkgTriangulation3 /*! \addtogroup PkgTriangulation3 @@ -111,6 +118,8 @@ is opposite to the vertex with the same index. See - `CGAL::Triangulation_3::Locate_type` +### Draw a Triangulation 3 ### +- `CGAL::draw` */ diff --git a/Triangulation_3/doc/Triangulation_3/Triangulation_3.txt b/Triangulation_3/doc/Triangulation_3/Triangulation_3.txt index 481610b3806..4d9385e07c8 100644 --- a/Triangulation_3/doc/Triangulation_3/Triangulation_3.txt +++ b/Triangulation_3/doc/Triangulation_3/Triangulation_3.txt @@ -535,6 +535,20 @@ removal of the first 100,000 vertices. \cgalExample{Triangulation_3/parallel_insertion_and_removal_in_regular_3.cpp} +\subsection Triangulation3Draw Draw a 3D Triangulation +\anchor ssecDrawT3 + +A 3D triangulation can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given 3D triangulation. The function is blocking, that is the program continues as soon as the user closes the window. + +\cgalExample{Triangulation_3/draw_triangulation_3.cpp} + +This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. + +\cgalFigureBegin{fig_draw_triangulation_3,draw_triangulation_3.png} +Result of the run of the draw_triangulation_3 program. A window shows the 3D triangulation and allows to navigate through the 3D scene. +\cgalFigureEnd + + \section Triangulation3seccomplexity Complexity and Performance In 3D, the worst case complexity of a triangulation is quadratic in the number diff --git a/Triangulation_3/doc/Triangulation_3/examples.txt b/Triangulation_3/doc/Triangulation_3/examples.txt index 78ba6d23c9a..1a34261199c 100644 --- a/Triangulation_3/doc/Triangulation_3/examples.txt +++ b/Triangulation_3/doc/Triangulation_3/examples.txt @@ -13,4 +13,5 @@ \example Triangulation_3/copy_triangulation_3.cpp \example Triangulation_3/parallel_insertion_in_delaunay_3.cpp \example Triangulation_3/parallel_insertion_and_removal_in_regular_3.cpp +\example Triangulation_3/draw_triangulation_3.cpp */ diff --git a/Triangulation_3/doc/Triangulation_3/fig/draw_triangulation_3.png b/Triangulation_3/doc/Triangulation_3/fig/draw_triangulation_3.png new file mode 100644 index 00000000000..486aab9df08 Binary files /dev/null and b/Triangulation_3/doc/Triangulation_3/fig/draw_triangulation_3.png differ diff --git a/Triangulation_3/examples/Triangulation_3/CMakeLists.txt b/Triangulation_3/examples/Triangulation_3/CMakeLists.txt index c9673ba28b7..c13b8b4bbe0 100644 --- a/Triangulation_3/examples/Triangulation_3/CMakeLists.txt +++ b/Triangulation_3/examples/Triangulation_3/CMakeLists.txt @@ -2,8 +2,16 @@ project( Triangulation_3_Examples ) cmake_minimum_required(VERSION 2.8.12) +if(NOT POLICY CMP0070 AND POLICY CMP0053) + # Only set CMP0053 to OLD with CMake<3.10, otherwise there is a warning. + cmake_policy(SET CMP0053 OLD) +endif() -find_package(CGAL QUIET) +find_package(CGAL COMPONENTS Qt5) + +if(CGAL_Qt5_FOUND) + add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS) +endif() if ( CGAL_FOUND ) create_single_source_cgal_program( "adding_handles_3.cpp" ) @@ -20,19 +28,9 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "simple_triangulation_3.cpp" ) create_single_source_cgal_program( "simplex.cpp" ) - find_package( TBB QUIET ) - - if( TBB_FOUND ) - include( CGAL_target_use_TBB ) - - create_single_source_cgal_program( "parallel_insertion_and_removal_in_regular_3.cpp" ) - create_single_source_cgal_program( "parallel_insertion_in_delaunay_3.cpp" ) - create_single_source_cgal_program( "sequential_parallel.cpp" ) - CGAL_target_use_TBB( parallel_insertion_and_removal_in_regular_3 ) - CGAL_target_use_TBB( parallel_insertion_in_delaunay_3 ) - CGAL_target_use_TBB( sequential_parallel ) - else() - message(STATUS "NOTICE: a few examples require TBB and will not be compiled.") + create_single_source_cgal_program("draw_triangulation_3.cpp") + if(CGAL_Qt5_FOUND) + target_link_libraries(draw_triangulation_3 PUBLIC CGAL::CGAL_Qt5) endif() else() diff --git a/Triangulation_3/examples/Triangulation_3/draw_triangulation_3.cpp b/Triangulation_3/examples/Triangulation_3/draw_triangulation_3.cpp new file mode 100644 index 00000000000..3806854f938 --- /dev/null +++ b/Triangulation_3/examples/Triangulation_3/draw_triangulation_3.cpp @@ -0,0 +1,21 @@ +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Delaunay_triangulation_3 DT3; +typedef CGAL::Creator_uniform_3 Creator; + +int main() +{ + std::vector points; + CGAL::Random_points_in_sphere_3 g(1.0); + CGAL::cpp11::copy_n(g, 50, std::back_inserter(points)); + + DT3 dt3(points.begin(), points.end()); + + CGAL::draw(dt3); + + return EXIT_SUCCESS; +} diff --git a/Triangulation_3/examples/Triangulation_3/info_insert_with_transform_iterator.cpp b/Triangulation_3/examples/Triangulation_3/info_insert_with_transform_iterator.cpp index 9b84be9b8af..26aba0288f7 100644 --- a/Triangulation_3/examples/Triangulation_3/info_insert_with_transform_iterator.cpp +++ b/Triangulation_3/examples/Triangulation_3/info_insert_with_transform_iterator.cpp @@ -13,7 +13,7 @@ typedef Delaunay::Point Point; //a functor that returns a std::pair. //the unsigned integer is incremented at each call to //operator() -struct Auto_count : public CGAL::unary_function >{ +struct Auto_count : public CGAL::cpp98::unary_function >{ mutable unsigned i; Auto_count() : i(0){} std::pair operator()(const Point& p) const { diff --git a/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h b/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h index 215acb5ea58..331a661c73d 100644 --- a/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h +++ b/Triangulation_3/include/CGAL/Delaunay_triangulation_3.h @@ -571,11 +571,6 @@ public: // internal methods OutputItCells fit); public: - -#ifndef CGAL_NO_DEPRECATED_CODE - CGAL_DEPRECATED Vertex_handle move_point(Vertex_handle v, const Point & p); -#endif - template @@ -1278,31 +1273,6 @@ insert_and_give_new_cells(const Point& p, return v; } -#ifndef CGAL_NO_DEPRECATED_CODE -template < class Gt, class Tds, class Lds > -typename Delaunay_triangulation_3::Vertex_handle -Delaunay_triangulation_3:: -move_point(Vertex_handle v, const Point & p) -{ - CGAL_triangulation_precondition(! is_infinite(v)); - CGAL_triangulation_expensive_precondition(is_vertex(v)); - - // Dummy implementation for a start. - - // Remember an incident vertex to restart - // the point location after the removal. - Cell_handle c = v->cell(); - Vertex_handle old_neighbor = c->vertex(c->index(v) == 0 ? 1 : 0); - CGAL_triangulation_assertion(old_neighbor != v); - - remove(v); - - if (dimension() <= 0) - return insert(p); - return insert(p, old_neighbor->cell()); -} -#endif - template template class Delaunay_triangulation_3::Vertex_remover { diff --git a/Triangulation_3/include/CGAL/Regular_triangulation_3.h b/Triangulation_3/include/CGAL/Regular_triangulation_3.h index 8e8e5900045..8692371ebb2 100644 --- a/Triangulation_3/include/CGAL/Regular_triangulation_3.h +++ b/Triangulation_3/include/CGAL/Regular_triangulation_3.h @@ -426,7 +426,8 @@ namespace CGAL { template struct Index_to_Bare_point { - const Bare_point& operator()(const std::size_t& i) const + typename boost::result_of::type + operator()(const std::size_t& i) const { return cp(c[i]); } @@ -827,10 +828,6 @@ namespace CGAL { CGAL_triangulation_expensive_postcondition(is_valid()); } - - // DISPLACEMENT - Vertex_handle move_point(Vertex_handle v, const Weighted_point & p); - // Displacement works only for regular triangulation // without hidden points at any time Vertex_handle move_if_no_collision(Vertex_handle v, const Weighted_point & p); @@ -2433,30 +2430,6 @@ namespace CGAL { return removed; } - // Again, verbatim copy from Delaunay. - template < class Gt, class Tds, class Lds > - typename Regular_triangulation_3::Vertex_handle - Regular_triangulation_3:: - move_point(Vertex_handle v, const Weighted_point & p) - { - CGAL_triangulation_precondition(! is_infinite(v)); - CGAL_triangulation_expensive_precondition(is_vertex(v)); - - // Dummy implementation for a start. - - // Remember an incident vertex to restart - // the point location after the removal. - Cell_handle c = v->cell(); - Vertex_handle old_neighbor = c->vertex(c->index(v) == 0 ? 1 : 0); - CGAL_triangulation_assertion(old_neighbor != v); - - remove(v); - - if (dimension() <= 0) - return insert(p); - return insert(p, old_neighbor->cell()); - } - // Displacement works only for regular triangulation // without hidden points at any time template < class Gt, class Tds, class Lds > diff --git a/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h b/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h index 42f5eb46103..26d215222d2 100644 --- a/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h +++ b/Triangulation_3/include/CGAL/Triangulation_hierarchy_3.h @@ -24,9 +24,18 @@ #include +// Commented because the class is actually used by Delaunay_triangulation_hierarchy_3.h // #define CGAL_DEPRECATED_HEADER "" // #include +// This class is deprecated, but must be kept for backward compatibility. +// +// It would be better to move its content to the Delaunay_triangulation_3 +// specializations for Fast_location and make Triangulation_hierarchy_3 the +// empty nutshell instead. +// +// Then, later, maybe merge the Compact/Fast codes in a cleaner factorized way. + #include #include #include @@ -55,14 +64,6 @@ namespace CGAL { -// This class is deprecated, but must be kept for backward compatibility. -// -// It would be better to move its content to the Delaunay_triangulation_3 -// specializations for Fast_location and make Triangulation_hierarchy_3 the -// empty nutshell instead. -// -// Then, later, maybe merge the Compact/Fast codes in a cleaner factorized way. - template < class Tr > class Triangulation_hierarchy_3 : public Tr @@ -354,10 +355,6 @@ public: return n - this->number_of_vertices(); } -#ifndef CGAL_NO_DEPRECATED_CODE - CGAL_DEPRECATED Vertex_handle move_point(Vertex_handle v, const Point & p); -#endif - Vertex_handle move_if_no_collision(Vertex_handle v, const Point &p); Vertex_handle move(Vertex_handle v, const Point &p); @@ -718,34 +715,6 @@ remove_and_give_new_cells(Vertex_handle v, OutputItCells fit) } } -#ifndef CGAL_NO_DEPRECATED_CODE -template < class Tr > -typename Triangulation_hierarchy_3
::Vertex_handle -Triangulation_hierarchy_3:: -move_point(Vertex_handle v, const Point & p) -{ - CGAL_triangulation_precondition(v != Vertex_handle()); - Vertex_handle old, ret; - - for (std::size_t l = 0; l < maxlevel; ++l) { - Vertex_handle u = v->up(); - Vertex_handle w = hierarchy[l]->move_point(v, p); - if (l == 0) { - ret = w; - } - else { - set_up_down(w, old); - } - if (u == Vertex_handle()) - break; - old = w; - v = u; - } - - return ret; -} -#endif - template typename Triangulation_hierarchy_3::Vertex_handle Triangulation_hierarchy_3:: diff --git a/Triangulation_3/include/CGAL/draw_triangulation_3.h b/Triangulation_3/include/CGAL/draw_triangulation_3.h new file mode 100644 index 00000000000..709bd15924f --- /dev/null +++ b/Triangulation_3/include/CGAL/draw_triangulation_3.h @@ -0,0 +1,192 @@ +// Copyright (c) 2018 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0+ +// +// Author(s) : Guillaume Damiand + +#ifndef CGAL_DRAW_T3_H +#define CGAL_DRAW_T3_H + +#include +#include + +#ifdef CGAL_USE_BASIC_VIEWER + +#include + +namespace CGAL +{ + +// Default color functor; user can change it to have its own face color +struct DefaultColorFunctorT3 +{ + template + static CGAL::Color run(const T3&, + const typename T3::Finite_facets_iterator* fh) + { + if (fh==NULL) // use to get the mono color + return CGAL::Color(100, 125, 200); // R G B between 0-255 + + CGAL::Random random((unsigned int)((std::size_t)(&*((*fh)->first))+ + (std::size_t)((*fh)->second))); + return get_random_color(random); + } +}; + +// Viewer class for T3 +template +class SimpleTriangulation3ViewerQt : public Basic_viewer_qt +{ + typedef Basic_viewer_qt Base; + typedef typename T3::Vertex_handle Vertex_const_handle; + typedef typename T3::Finite_edges_iterator Edge_const_handle; + typedef typename T3::Finite_facets_iterator Facet_const_handle; + typedef typename T3::Cell_handle Cell_handle; + typedef typename T3::Point Point; + +public: + /// Construct the viewer. + /// @param at3 the t3 to view + /// @param title the title of the window + /// @param anofaces if true, do not draw faces (faces are not computed; this can be + /// usefull for very big object where this time could be long) + SimpleTriangulation3ViewerQt(QWidget* parent, + const T3& at3, + const char* title="Basic T3 Viewer", + bool anofaces=false, + const ColorFunctor& fcolor=ColorFunctor()) : + // First draw: vertices; edges, faces; multi-color; no inverse normal + Base(parent, title, true, true, true, false, false), + t3(at3), + m_nofaces(anofaces), + m_fcolor(fcolor) + { + compute_elements(); + } + +protected: + void compute_face(Facet_const_handle fh) + { + CGAL::Color c=m_fcolor.run(t3, &fh); + face_begin(c); + + add_point_in_face(fh->first->vertex((fh->second+1)%4)->point()); + add_point_in_face(fh->first->vertex((fh->second+2)%4)->point()); + add_point_in_face(fh->first->vertex((fh->second+3)%4)->point()); + + face_end(); + } + + void compute_edge(Edge_const_handle eh) + { + add_segment(eh->first->vertex(eh->second)->point(), + eh->first->vertex(eh->third)->point()); + } + + void compute_vertex(Vertex_const_handle vh) + { add_point(vh->point()); } + + void compute_elements() + { + clear(); + + if (!m_nofaces) + { + for (typename T3::Finite_facets_iterator it=t3.finite_facets_begin(); + it!=t3.finite_facets_end(); ++it) + { compute_face(it); } + } + + for (typename T3::Finite_edges_iterator it=t3.finite_edges_begin(); + it!=t3.finite_edges_end(); ++it) + { compute_edge(it); } + + for (typename T3::Finite_vertices_iterator it=t3.finite_vertices_begin(); + it!=t3.finite_vertices_end(); ++it) + { compute_vertex(it); } + } + + virtual void keyPressEvent(QKeyEvent *e) + { + // Test key pressed: + // const ::Qt::KeyboardModifiers modifiers = e->modifiers(); + // if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) { ... } + + // Call: * compute_elements() if the model changed, followed by + // * redraw() if some viewing parameters changed that implies some + // modifications of the buffers + // (eg. type of normal, color/mono) + // * update() just to update the drawing + + // Call the base method to process others/classicals key + Base::keyPressEvent(e); + } + +protected: + const T3& t3; + bool m_nofaces; + const ColorFunctor& m_fcolor; +}; + +template +void draw(const T3& at3, + const char* title, + bool nofill, + const ColorFunctor& fcolor) +{ + +#if defined(CGAL_TEST_SUITE) + bool cgal_test_suite=true; +#else + bool cgal_test_suite=false; +#endif + + if (!cgal_test_suite) + { + int argc=1; + const char* argv[2]={"t3_viewer","\0"}; + QApplication app(argc,const_cast(argv)); + SimpleTriangulation3ViewerQt mainwindow(app.activeWindow(), + at3, + title, + nofill, + fcolor); + mainwindow.show(); + app.exec(); + } +} + +template +void draw(const T3& at3, const char* title, bool nofill) +{ + DefaultColorFunctorT3 c; + draw(at3, title, nofill, c); +} + +template +void draw(const T3& at3, const char* title) +{ draw(at3, title, false); } + +template +void draw(const T3& at3) +{ draw(at3, "Basic T3 Viewer"); } + +} // End namespace CGAL + +#endif // CGAL_USE_BASIC_VIEWER + +#endif // CGAL_DRAW_T3_H diff --git a/Triangulation_3/package_info/Triangulation_3/dependencies b/Triangulation_3/package_info/Triangulation_3/dependencies index c07b218e4eb..df63288cf1d 100644 --- a/Triangulation_3/package_info/Triangulation_3/dependencies +++ b/Triangulation_3/package_info/Triangulation_3/dependencies @@ -7,6 +7,7 @@ Distance_2 Distance_3 Filtered_kernel Geomview +GraphicsView Hash_map Homogeneous_kernel Installation diff --git a/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_delaunay_3.h b/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_delaunay_3.h index 4c715b46c27..dd437b26bd7 100644 --- a/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_delaunay_3.h +++ b/Triangulation_3/test/Triangulation_3/include/CGAL/_test_cls_delaunay_3.h @@ -618,33 +618,6 @@ _test_cls_delaunay_3(const Triangulation &) assert(T3_13.number_of_vertices()==22); assert(T3_13.dimension()==3); -#ifndef CGAL_NO_DEPRECATED_CODE - { - std::cout << " Testing move_point()" << std::endl; - Cls T; - std::list L; - for (i=0; i<22; ++i) - L.push_back(T.insert(q[i])); - assert(T.is_valid()); - assert(T.number_of_vertices()==22); - assert(T.dimension()==3); - - for (i=0; i<100; ++i) { - assert(!L.empty()); - Vertex_handle v = L.front(); - L.pop_front(); - size_type nbv = T.number_of_vertices(); - L.push_back(T.move_point(v, q[(3*i)%22])); - - if (nbv != T.number_of_vertices()) - L.pop_back(); // it means we move onto an already existing point. - - assert(T.is_valid()); - assert(T.number_of_vertices()<=22); - } - } -#endif - { std::cout << " Testing move()" << std::endl; Cls T; diff --git a/Triangulation_3/test/Triangulation_3/test_delaunay_3.cpp b/Triangulation_3/test/Triangulation_3/test_delaunay_3.cpp index 4b14f8b34b3..1c43a50521a 100644 --- a/Triangulation_3/test/Triangulation_3/test_delaunay_3.cpp +++ b/Triangulation_3/test/Triangulation_3/test_delaunay_3.cpp @@ -19,7 +19,7 @@ // // Author(s) : Francois Rebufat -#define CGAL_NO_DEPRECATION_WARNINGS +#include #include "test_dependencies.h" diff --git a/Triangulation_3/test/Triangulation_3/test_delaunay_hierarchy_3.cpp b/Triangulation_3/test/Triangulation_3/test_delaunay_hierarchy_3.cpp index a2353551c0e..695e87e513e 100644 --- a/Triangulation_3/test/Triangulation_3/test_delaunay_hierarchy_3.cpp +++ b/Triangulation_3/test/Triangulation_3/test_delaunay_hierarchy_3.cpp @@ -19,8 +19,6 @@ // // Author(s) : Mariette Yvinec, Sylvain Pion -#define CGAL_NO_DEPRECATION_WARNINGS - #include bool del=true; diff --git a/Triangulation_3/test/Triangulation_3/test_delaunay_hierarchy_3_old.cpp b/Triangulation_3/test/Triangulation_3/test_delaunay_hierarchy_3_old.cpp index 8f688d91158..d897cca8d2c 100644 --- a/Triangulation_3/test/Triangulation_3/test_delaunay_hierarchy_3_old.cpp +++ b/Triangulation_3/test/Triangulation_3/test_delaunay_hierarchy_3_old.cpp @@ -19,8 +19,6 @@ // // Author(s) : Mariette Yvinec, Sylvain Pion -#define CGAL_NO_DEPRECATION_WARNINGS - #include #include diff --git a/Triangulation_3/test/Triangulation_3/test_regular_insert_range_with_info.cpp b/Triangulation_3/test/Triangulation_3/test_regular_insert_range_with_info.cpp index 31a0bb1d85d..f982cec76cb 100644 --- a/Triangulation_3/test/Triangulation_3/test_regular_insert_range_with_info.cpp +++ b/Triangulation_3/test/Triangulation_3/test_regular_insert_range_with_info.cpp @@ -1,184 +1,226 @@ - #include "test_dependencies.h" + #include +#include + #include #include + +#include + +#include +#include #include -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef K Traits; -typedef CGAL::Regular_triangulation_vertex_base_3 Vbb; -typedef CGAL::Triangulation_vertex_base_with_info_3 Vb; -typedef CGAL::Triangulation_data_structure_3 > Tds; -typedef CGAL::Regular_triangulation_3 Regular; -typedef K::Weighted_point_3 Weighted_point; -typedef K::Point_3 Point; +typedef CGAL::Exact_predicates_exact_constructions_kernel K; + +template +struct Tester +{ + typedef K Traits; + typedef CGAL::Regular_triangulation_vertex_base_3 Vbb; + typedef CGAL::Triangulation_vertex_base_with_info_3 Vb; + typedef CGAL::Regular_triangulation_cell_base_3 Cb; + typedef CGAL::Triangulation_data_structure_3 Tds; + + typedef CGAL::Regular_triangulation_3 RT; + typedef typename RT::Bare_point Bare_point; + typedef typename RT::Weighted_point Weighted_point; #ifdef CGAL_LINKED_WITH_TBB -typedef CGAL::Spatial_lock_grid_3 Lock_ds; -typedef CGAL::Triangulation_data_structure_3, CGAL::Parallel_tag> Tds_parallel; -typedef CGAL::Regular_triangulation_3 RT_parallel; + typedef CGAL::Spatial_lock_grid_3 Lock_ds; + typedef CGAL::Triangulation_data_structure_3 Tds_parallel; + typedef CGAL::Regular_triangulation_3 RT_parallel; #endif -template -void test_iterator_on_pair(){ - typedef std::vector< std::pair > Container; - typedef typename boost::mpl::if_< boost::mpl::bool_,boost::add_const::type,Container >::type Cast_type; - Container points; - - - points.push_back( std::make_pair( Weighted_point(Point(0,0,0),1),0 ) ); - points.push_back( std::make_pair( Weighted_point(Point(1,0,0),2),1 ) ); - points.push_back( std::make_pair( Weighted_point(Point(0,1,0),3),2 ) ); - points.push_back( std::make_pair( Weighted_point(Point(0,0,1),4),3 ) ); - points.push_back( std::make_pair( Weighted_point(Point(2,2,2),5),4 ) ); - points.push_back( std::make_pair( Weighted_point(Point(-1,0,1),6),5 ) ); - - - Regular R( static_cast(points).begin(),static_cast(points).end() ); - - assert( R.number_of_vertices() == 6 ); - - // check that the info was correctly set. - Regular::Finite_vertices_iterator vit; - for (vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) - assert(points[vit->info()].first == vit->point()); - -#ifdef CGAL_LINKED_WITH_TBB + template + void test_iterator_on_pair() const { - // Construct the locking data-structure, using the bounding-box of the points - typename RT_parallel::Lock_data_structure locking_ds( - CGAL::Bbox_3(-1., 0., 0., 2, 2, 2), 50); - // Contruct the triangulation in parallel - RT_parallel R( - static_cast(points).begin(), - static_cast(points).end(), - &locking_ds); + typedef std::vector > Container; + typedef typename boost::mpl::if_, + typename boost::add_const::type, + Container>::type Cast_type; - assert(R.number_of_vertices() == 6); + Container points; + points.push_back(std::make_pair(Weighted_point(Bare_point(0.160385, 0.599679, 0.374932), -0.118572), 0)); + points.push_back(std::make_pair(Weighted_point(Bare_point(0.17093, 0.82228, 0.51697), -0.0226131), 1)); + points.push_back(std::make_pair(Weighted_point(Bare_point(0.15773, 0.66293, 0.458541), -0.0753074), 2)); + points.push_back(std::make_pair(Weighted_point(Bare_point(0.388417, 0.685989, 0.401349), -0.0616195), 3)); + points.push_back(std::make_pair(Weighted_point(Bare_point(0.380061, 0.852124, 0.538984), -0.0145638), 4)); + points.push_back(std::make_pair(Weighted_point(Bare_point(0.0402467, 0.519724, 0.417205), -0.0698374), 5)); + points.push_back(std::make_pair(Weighted_point(Bare_point(0.0270472, 0.360373, 0.358776), -0.0109982), 6)); + points.push_back(std::make_pair(Weighted_point(Bare_point(0.257734, 0.383432, 0.301584), -0.0601458), 7)); + points.push_back(std::make_pair(Weighted_point(Bare_point(0.142091, 0.643406, 0.61943), -0.251061), 8)); - // check that the info was correctly set. - RT_parallel::Finite_vertices_iterator vit; - for (vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) - assert(points[vit->info()].first == vit->point()); - } + RT R(static_cast(points).begin(), static_cast(points).end()); + assert(R.number_of_vertices() == 9); + + R.clear(); + R.insert(static_cast(points).begin(), static_cast(points).end()); + assert(R.number_of_vertices() == 9); + + // check that the info was correctly set. + typename RT::Finite_vertices_iterator vit; + for(vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) + assert(points[vit->info()].first == vit->point()); + + #ifdef CGAL_LINKED_WITH_TBB + { + // Construct the locking data-structure, using the bounding-box of the points + typename RT_parallel::Lock_data_structure locking_ds(CGAL::Bbox_3(-1., 0., 0., 2, 2, 2), 50); + + // Contruct the triangulation in parallel + RT_parallel R(static_cast(points).begin(), static_cast(points).end(), &locking_ds); + assert(R.number_of_vertices() == 9); + + R.clear(); + R.insert(static_cast(points).begin(), static_cast(points).end(), &locking_ds); + assert(R.number_of_vertices() == 9); + + // check that the info was correctly set. + typename RT_parallel::Finite_vertices_iterator vit; + for(vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) { + assert(points[vit->info()].first == vit->point()); + } + } #endif -} + } -void toto(int){} - -template -void test_zip_iterator(){ - typedef std::vector< Weighted_point > Container; - Container points; - typedef typename boost::mpl::if_< boost::mpl::bool_,boost::add_const::type,Container >::type Cast_type; - - points.push_back( Weighted_point(Point(0,0,0),1) ); - points.push_back( Weighted_point(Point(1,0,0),2) ); - points.push_back( Weighted_point(Point(0,1,0),3) ); - points.push_back( Weighted_point(Point(0,0,1),4) ); - points.push_back( Weighted_point(Point(2,2,2),5) ); - points.push_back( Weighted_point(Point(-1,0,1),6) ); - - std::vector indices; - indices.push_back(0); - indices.push_back(1); - indices.push_back(2); - indices.push_back(3); - indices.push_back(4); - indices.push_back(5); - - Regular R( boost::make_zip_iterator(boost::make_tuple( static_cast(points).begin(),indices.begin() )), - boost::make_zip_iterator(boost::make_tuple( static_cast(points).end(),indices.end() ) ) ); - assert( R.number_of_vertices() == 6 ); - - // check that the info was correctly set. - Regular::Finite_vertices_iterator vit; - for (vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) - assert( points[ vit->info() ] == vit->point() ); - -#ifdef CGAL_LINKED_WITH_TBB + template + void test_zip_iterator() const { - // Construct the locking data-structure, using the bounding-box of the points - typename RT_parallel::Lock_data_structure locking_ds( - CGAL::Bbox_3(-1., 0., 0., 2, 2, 2), 50); - // Contruct the triangulation in parallel - RT_parallel R( - boost::make_zip_iterator(boost::make_tuple(static_cast(points).begin(), indices.begin())), - boost::make_zip_iterator(boost::make_tuple(static_cast(points).end(), indices.end())), - &locking_ds); + typedef std::vector Container; + typedef typename boost::mpl::if_, + typename boost::add_const::type, + Container >::type Cast_type; - assert(R.number_of_vertices() == 6); + Container points; + points.push_back(Weighted_point(Bare_point(0,0,0),1)); + points.push_back(Weighted_point(Bare_point(1,0,0),2)); + points.push_back(Weighted_point(Bare_point(0,1,0),3)); + points.push_back(Weighted_point(Bare_point(0,0,1),4)); + points.push_back(Weighted_point(Bare_point(2,2,2),5)); + points.push_back(Weighted_point(Bare_point(-1,0,1),6)); - // check that the info was correctly set. - RT_parallel::Finite_vertices_iterator vit; - for (vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) - assert(points[vit->info()] == vit->point()); - } + std::vector indices; + indices.push_back(0); + indices.push_back(1); + indices.push_back(2); + indices.push_back(3); + indices.push_back(4); + indices.push_back(5); + + RT R(boost::make_zip_iterator(boost::make_tuple(static_cast(points).begin(), indices.begin())), + boost::make_zip_iterator(boost::make_tuple(static_cast(points).end(), indices.end()))); + assert(R.number_of_vertices() == 6); + + // check that the info was correctly set. + typename RT::Finite_vertices_iterator vit; + for(vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) + assert(points[ vit->info() ] == vit->point()); + +#ifdef CGAL_LINKED_WITH_TBB + { + // Construct the locking data-structure, using the bounding-box of the points + typename RT_parallel::Lock_data_structure locking_ds(CGAL::Bbox_3(-1., 0., 0., 2, 2, 2), 50); + + // Contruct the triangulation in parallel + RT_parallel R(boost::make_zip_iterator(boost::make_tuple(static_cast(points).begin(), indices.begin())), + boost::make_zip_iterator(boost::make_tuple(static_cast(points).end(), indices.end())), + &locking_ds); + assert(R.number_of_vertices() == 6); + + // check that the info was correctly set. + typename RT_parallel::Finite_vertices_iterator vit; + for(vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) { + assert(points[vit->info()] == vit->point()); + } + } #endif -} + } -struct Auto_count : public CGAL::unary_function >{ - mutable unsigned i; - Auto_count() : i(0){} - std::pair operator()(const Weighted_point& p) const { - return std::make_pair(p,i++); + struct Auto_count + : public CGAL::cpp98::unary_function > + { + mutable unsigned i; + Auto_count() : i(0){} + std::pair operator()(const Weighted_point& p) const + { + return std::make_pair(p,i++); + } + }; + + template + void test_transform_iterator() const + { + typedef std::vector< Weighted_point > Container; + typedef typename boost::mpl::if_, + typename boost::add_const::type, + Container >::type Cast_type; + + Container points; + points.push_back(Weighted_point(Bare_point(0,0,0),1)); + points.push_back(Weighted_point(Bare_point(1,0,0),2)); + points.push_back(Weighted_point(Bare_point(0,1,0),3)); + points.push_back(Weighted_point(Bare_point(0,0,1),4)); + points.push_back(Weighted_point(Bare_point(2,2,2),5)); + points.push_back(Weighted_point(Bare_point(-1,0,1),6)); + + RT R(boost::make_transform_iterator(static_cast(points).begin(), Auto_count()), + boost::make_transform_iterator(static_cast(points).end(), Auto_count())); + + assert(R.number_of_vertices() == 6); + + // check that the info was correctly set. + typename RT::Finite_vertices_iterator vit; + for(vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) + assert(points[ vit->info() ] == vit->point()); + +#ifdef CGAL_LINKED_WITH_TBB + { + // Construct the locking data-structure, using the bounding-box of the points + typename RT_parallel::Lock_data_structure locking_ds(CGAL::Bbox_3(-1., 0., 0., 2, 2, 2), 50); + + // Contruct the triangulation in parallel + RT_parallel R(boost::make_transform_iterator(static_cast(points).begin(), Auto_count()), + boost::make_transform_iterator(static_cast(points).end(), Auto_count()), + &locking_ds); + assert(R.number_of_vertices() == 6); + + // check that the info was correctly set. + typename RT_parallel::Finite_vertices_iterator vit; + for(vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) { + assert(points[vit->info()] == vit->point()); + } + } +#endif + } + + void operator()() const + { + test_iterator_on_pair(); + test_iterator_on_pair(); + test_zip_iterator(); + test_zip_iterator(); + test_transform_iterator(); + test_transform_iterator(); } }; -template -void test_transform_iterator(){ - typedef std::vector< Weighted_point > Container; - Container points; - typedef typename boost::mpl::if_< boost::mpl::bool_,boost::add_const::type,Container >::type Cast_type; - - points.push_back( Weighted_point(Point(0,0,0),1) ); - points.push_back( Weighted_point(Point(1,0,0),2) ); - points.push_back( Weighted_point(Point(0,1,0),3) ); - points.push_back( Weighted_point(Point(0,0,1),4) ); - points.push_back( Weighted_point(Point(2,2,2),5) ); - points.push_back( Weighted_point(Point(-1,0,1),6) ); - - Regular R( boost::make_transform_iterator(static_cast(points).begin(),Auto_count()), - boost::make_transform_iterator(static_cast(points).end(), Auto_count() ) ); - - assert( R.number_of_vertices() == 6 ); - - // check that the info was correctly set. - Regular::Finite_vertices_iterator vit; - for (vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) - assert( points[ vit->info() ] == vit->point() ); - -#ifdef CGAL_LINKED_WITH_TBB - { - // Construct the locking data-structure, using the bounding-box of the points - typename RT_parallel::Lock_data_structure locking_ds( - CGAL::Bbox_3(-1., 0., 0., 2, 2, 2), 50); - // Contruct the triangulation in parallel - RT_parallel R( - boost::make_transform_iterator(static_cast(points).begin(), Auto_count()), - boost::make_transform_iterator(static_cast(points).end(), Auto_count()), - &locking_ds); - - assert(R.number_of_vertices() == 6); - - // check that the info was correctly set. - RT_parallel::Finite_vertices_iterator vit; - for (vit = R.finite_vertices_begin(); vit != R.finite_vertices_end(); ++vit) - assert(points[vit->info()] == vit->point()); - } -#endif -} - int main() { - test_iterator_on_pair(); - test_iterator_on_pair(); - test_zip_iterator(); - test_zip_iterator(); - test_transform_iterator(); - test_transform_iterator(); - return 0; -} + typedef CGAL::Exact_predicates_inexact_constructions_kernel Epick; + typedef CGAL::Exact_predicates_exact_constructions_kernel Epeck; + std::cerr << "TESTING WITH Exact_predicates_inexact_constructions_kernel...\n"; + Tester test_epic; + test_epic(); + + std::cerr << "TESTING WITH Exact_predicates_exact_constructions_kernel...\n"; + Tester test_epec; + test_epec(); + + return EXIT_SUCCESS; +} diff --git a/Triangulation_3/test/Triangulation_3/test_regular_traits_3.cpp b/Triangulation_3/test/Triangulation_3/test_regular_traits_3.cpp index ac24036c9ee..ccecd2c6979 100644 --- a/Triangulation_3/test/Triangulation_3/test_regular_traits_3.cpp +++ b/Triangulation_3/test/Triangulation_3/test_regular_traits_3.cpp @@ -20,7 +20,7 @@ // // Author(s) : Mariette Yvinec -#define CGAL_NO_DEPRECATION_WARNINGS +#include #include #include diff --git a/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h b/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h index f00bb75a9f0..0426427d580 100644 --- a/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h +++ b/Visibility_2/include/CGAL/Rotational_sweep_visibility_2.h @@ -73,7 +73,7 @@ private: typedef Halfedge_const_handle EH; typedef std::vector EHs; - class Less_edge: public CGAL::binary_function { + class Less_edge: public CGAL::cpp98::binary_function { const Geometry_traits_2* geom_traits; public: Less_edge() {} @@ -94,7 +94,7 @@ private: } }; - class Less_vertex: public CGAL::binary_function { + class Less_vertex: public CGAL::cpp98::binary_function { const Geometry_traits_2* geom_traits; public: Less_vertex() {} @@ -110,7 +110,7 @@ private: } }; - class Closer_edge: public CGAL::binary_function { + class Closer_edge: public CGAL::cpp98::binary_function { const Geometry_traits_2* geom_traits; Point_2 q; public: @@ -729,7 +729,7 @@ private: //functor to decide which vertex is swept earlier by the rotational sweeping //ray - class Is_swept_earlier:public CGAL::binary_function { + class Is_swept_earlier:public CGAL::cpp98::binary_function { const Point_2& q; const Geometry_traits_2* geom_traits; public:
Doxygen 1.8.4Doxygen 1.8.13(official)Doxygen master
Package Name Logs
"); + const QString tdtr("
" + left + tdtd + right + tdtr; + even = !even; + + return res; +} + +/*! Returns a QString that describes the application mouse bindings, displayed +in the help() window \c Mouse tab. + +Result is a table that describes custom application mouse binding descriptions +defined using setMouseBindingDescription() as well as standard mouse bindings +(defined using setMouseBinding() and setWheelBinding()). See the mouse page for details on mouse bindings. + +See also helpString() and keyboardString(). */ +CGAL_INLINE_FUNCTION +QString CGAL::QGLViewer::mouseString() const { + QString text( + "
\n"); + const QString trtd("\n"); + const QString tdtd("\n") + .arg(tr("Button(s)", + "Buttons column header in help window mouse tab")) + .arg(tr("Description", + "Description column header in help window mouse tab")); + + QMap mouseBinding; + + // User-defined mouse bindings come first. + for (QMap::ConstIterator + itm = mouseDescription_.begin(), + endm = mouseDescription_.end(); + itm != endm; ++itm) + mouseBinding[itm.key()] = itm.value(); + + for (QMap::ConstIterator + it = mouseBinding.begin(), + end = mouseBinding.end(); + it != end; ++it) { + // Should not be needed (see setMouseBindingDescription()) + if (it.value().isNull()) + continue; + + text += tableLine(formatClickActionPrivate(it.key()), it.value()); + } + + // Optional separator line + if (!mouseBinding.isEmpty()) { + mouseBinding.clear(); + text += QString("\n") + .arg(tr("Standard mouse bindings", "In help window mouse tab")); + } + + // Then concatenates the descriptions of wheelBinding_, mouseBinding_ and + // clickBinding_. The order is significant and corresponds to the priorities + // set in mousePressEvent() (reverse priority order, last one overwrites + // previous) #CONNECTION# mousePressEvent() order + for (QMap::ConstIterator + itmb = mouseBinding_.begin(), + endmb = mouseBinding_.end(); + itmb != endmb; ++itmb) { + ClickBindingPrivate cbp(itmb.key().modifiers, itmb.key().button, false, + ::Qt::NoButton, itmb.key().key); + + QString text = mouseActionString(itmb.value().action); + + if (!text.isNull()) { + switch (itmb.value().handler) { + case qglviewer::CAMERA: + text += " " + tr("camera", "Suffix after action"); + break; + case qglviewer::FRAME: + text += " " + tr("manipulated frame", "Suffix after action"); + break; + } + if (!(itmb.value().withConstraint)) + text += "*"; + } + mouseBinding[cbp] = text; + } + + for (QMap::ConstIterator + itw = wheelBinding_.begin(), + endw = wheelBinding_.end(); + itw != endw; ++itw) { + ClickBindingPrivate cbp(itw.key().modifiers, ::Qt::NoButton, false, + ::Qt::NoButton, itw.key().key); + + QString text = mouseActionString(itw.value().action); + + if (!text.isNull()) { + switch (itw.value().handler) { + case qglviewer::CAMERA: + text += " " + tr("camera", "Suffix after action"); + break; + case qglviewer::FRAME: + text += " " + tr("manipulated frame", "Suffix after action"); + break; + } + if (!(itw.value().withConstraint)) + text += "*"; + } + + mouseBinding[cbp] = text; + } + + for (QMap::ConstIterator + itcb = clickBinding_.begin(), + endcb = clickBinding_.end(); + itcb != endcb; ++itcb) + mouseBinding[itcb.key()] = clickActionString(itcb.value()); + + for (QMap::ConstIterator + it2 = mouseBinding.begin(), + end2 = mouseBinding.end(); + it2 != end2; ++it2) { + if (it2.value().isNull()) + continue; + + text += tableLine(formatClickActionPrivate(it2.key()), it2.value()); + } + + text += "
"); + const QString tdtr("
"); + + text += QString("
%1%2
%1
"; + + return text; +} + +/*! Defines a custom keyboard shortcut description, that will be displayed in +the help() window \c Keyboard tab. + +The \p key definition is given as an \c int using Qt enumerated values. Set an +empty \p description to remove a shortcut description: \code +setKeyDescription(::Qt::Key_W, "Toggles wireframe display"); +setKeyDescription(::Qt::CTRL+::Qt::Key_L, "Loads a new scene"); +// Removes a description +setKeyDescription(::Qt::CTRL+::Qt::Key_C, ""); +\endcode + +See the keyboardAndMouse example +for illustration and the keyboard page for +details. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setKeyDescription(unsigned int key, QString description) { + if (description.isEmpty()) + keyDescription_.remove(key); + else + keyDescription_[key] = description; +} + +CGAL_INLINE_FUNCTION +QString CGAL::QGLViewer::cameraPathKeysString() const { + if (pathIndex_.isEmpty()) + return QString::null; + + QVector< ::Qt::Key> keys; + keys.reserve(pathIndex_.count()); + for (QMap< ::Qt::Key, unsigned int>::ConstIterator i = pathIndex_.begin(), + endi = pathIndex_.end(); + i != endi; ++i) + keys.push_back(i.key()); + qSort(keys); + + QVector< ::Qt::Key>::const_iterator it = keys.begin(), end = keys.end(); + QString res = keyString(*it); + + const int maxDisplayedKeys = 6; + int nbDisplayedKeys = 0; + ::Qt::Key previousKey = (*it); + int state = 0; + ++it; + while ((it != end) && (nbDisplayedKeys < maxDisplayedKeys - 1)) { + switch (state) { + case 0: + if ((*it) == previousKey + 1) + state++; + else { + res += ", " + keyString(*it); + nbDisplayedKeys++; + } + break; + case 1: + if ((*it) == previousKey + 1) + state++; + else { + res += ", " + keyString(previousKey); + res += ", " + keyString(*it); + nbDisplayedKeys += 2; + state = 0; + } + break; + default: + if ((*it) != previousKey + 1) { + res += ".." + keyString(previousKey); + res += ", " + keyString(*it); + nbDisplayedKeys += 2; + state = 0; + } + break; + } + previousKey = *it; + ++it; + } + + if (state == 1) + res += ", " + keyString(previousKey); + if (state == 2) + res += ".." + keyString(previousKey); + if (it != end) + res += "..."; + + return res; +} + +/*! Returns a QString that describes the application keyboard shortcut bindings, +and that will be displayed in the help() window \c Keyboard tab. + +Default value is a table that describes the custom shortcuts defined using +setKeyDescription() as well as the \e standard CGAL::QGLViewer::KeyboardAction +shortcuts (defined using setShortcut()). See the keyboard page for details on key customization. + +See also helpString() and mouseString(). */ +CGAL_INLINE_FUNCTION +QString CGAL::QGLViewer::keyboardString() const { + QString text( + "
\n"); + text += QString("\n") + .arg(CGAL::QGLViewer::tr("Key(s)", + "Keys column header in help window mouse tab")) + .arg(CGAL::QGLViewer::tr( + "Description", + "Description column header in help window mouse tab")); + + QMap keyDescription; + + // 1 - User defined key descriptions + for (QMap::ConstIterator kd = keyDescription_.begin(), + kdend = keyDescription_.end(); + kd != kdend; ++kd) + keyDescription[kd.key()] = kd.value(); + + // Add to text in sorted order + for (QMap::ConstIterator kb = keyDescription.begin(), + endb = keyDescription.end(); + kb != endb; ++kb) + text += tableLine(keyString(kb.key()), kb.value()); + + // 2 - Optional separator line + if (!keyDescription.isEmpty()) { + keyDescription.clear(); + text += QString("\n") + .arg(CGAL::QGLViewer::tr("Standard viewer keys", + "In help window keys tab")); + } + + // 3 - KeyboardAction bindings description + for (QMap::ConstIterator + it = keyboardBinding_.begin(), + end = keyboardBinding_.end(); + it != end; ++it) + if ((it.value() != 0) && + ((!cameraIsInRotateMode()) || + ((it.key() != qglviewer::INCREASE_FLYSPEED) && (it.key() != qglviewer::DECREASE_FLYSPEED)))) + keyDescription[it.value()] = keyboardActionDescription_[it.key()]; + + // Add to text in sorted order + for (QMap::ConstIterator kb2 = keyDescription.begin(), + endb2 = keyDescription.end(); + kb2 != endb2; ++kb2) + text += tableLine(keyString(kb2.key()), kb2.value()); + + // 4 - Camera paths keys description + const QString cpks = cameraPathKeysString(); + if (!cpks.isNull()) { + text += "\n"; + text += tableLine( + keyString(playPathKeyboardModifiers()) + "" + + CGAL::QGLViewer::tr("Fx", "Generic function key (F1..F12)") + "", + CGAL::QGLViewer::tr("Plays path (or resets saved position)")); + text += tableLine( + keyString(addKeyFrameKeyboardModifiers()) + "" + + CGAL::QGLViewer::tr("Fx", "Generic function key (F1..F12)") + "", + CGAL::QGLViewer::tr("Adds a key frame to path (or defines a position)")); + text += tableLine( + keyString(addKeyFrameKeyboardModifiers()) + "" + + CGAL::QGLViewer::tr("Fx", "Generic function key (F1..F12)") + "+" + + CGAL::QGLViewer::tr("Fx", "Generic function key (F1..F12)") + "", + CGAL::QGLViewer::tr("Deletes path (or saved position)")); + } + text += "
%1%2
%1
\n"; + text += CGAL::QGLViewer::tr("Camera paths are controlled using the %1 keys " + "(noted Fx below):", + "Help window key tab camera keys") + .arg(cpks) + + "
"; + + return text; +} + +/*! Displays the help window "About" tab. See help() for details. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::aboutQGLViewer() { + help(); + helpWidget()->setCurrentIndex(3); +} + +/*! Opens a modal help window that includes four tabs, respectively filled with +helpString(), keyboardString(), mouseString() and about libCGAL::QGLViewer. + +Rich html-like text can be used (see the QStyleSheet documentation). This method +is called when the user presses the CGAL::QGLViewer::HELP key (default is 'H'). + +You can use helpWidget() to access to the help widget (to add/remove tabs, +change layout...). + +The helpRequired() signal is emitted. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::help() { + Q_EMIT helpRequired(); + + bool resize = false; + int width = 600; + int height = 400; + + static QString label[] = {tr("&Help", "Help window tab title"), + tr("&Keyboard", "Help window tab title"), + tr("&Mouse", "Help window tab title"), + tr("&About", "Help window about title")}; + + if (!helpWidget()) { + // Qt4 requires a NULL parent... + helpWidget_ = new QTabWidget(NULL); + helpWidget()->setWindowTitle(tr("Help", "Help window title")); + + resize = true; + for (int i = 0; i < 4; ++i) { + QTextEdit *tab = new QTextEdit(NULL); + tab->setReadOnly(true); + + helpWidget()->insertTab(i, tab, label[i]); + if (i == 3) { +#include "resources/qglviewer-icon.xpm" + QPixmap pixmap(qglviewer_icon); + tab->document()->addResource(QTextDocument::ImageResource, + QUrl("mydata://qglviewer-icon.xpm"), + QVariant(pixmap)); + } + } + } + + for (int i = 0; i < 4; ++i) { + QString text; + switch (i) { + case 0: + text = helpString(); + break; + case 1: + text = keyboardString(); + break; + case 2: + text = mouseString(); + break; + case 3: + text = QString("

") + + tr("

libQGLViewer

" + "

Forked from version 2.7.0


" + "A versatile 3D viewer based on OpenGL and Qt
" + "Copyright 2002-%2 Gilles Debunne
" + "%3") + .arg("2014") + .arg("http://www.libqglviewer.com") + + QString("
"); + break; + default: + break; + } + + QTextEdit *textEdit = (QTextEdit *)(helpWidget()->widget(i)); + textEdit->setHtml(text); + textEdit->setText(text); + + if (resize && (textEdit->height() > height)) + height = textEdit->height(); + } + + if (resize) + helpWidget()->resize(width, height + 40); // 40 pixels is ~ tabs' height + helpWidget()->show(); + helpWidget()->raise(); +} + +/*! Overloading of the \c QWidget method. + +Default keyboard shortcuts are defined using setShortcut(). Overload this method +to implement a specific keyboard binding. Call the original method if you do not +catch the event to preserve the viewer default key bindings: \code void +CGAL_INLINE_FUNCTION +Viewer::keyPressEvent(QKeyEvent *e) +{ + // Defines the Alt+R shortcut. + if ((e->key() == ::Qt::Key_R) && (e->modifiers() == ::Qt::AltModifier)) + { + myResetFunction(); + update(); // Refresh display + } + else + CGAL::QGLViewer::keyPressEvent(e); +} + +// With Qt 2 or 3, you would retrieve modifiers keys using : +// const ::Qt::ButtonState modifiers = (::Qt::ButtonState)(e->state() & +::Qt::KeyButtonMask); \endcode When you define a new keyboard shortcut, use +setKeyDescription() to provide a short description which is displayed in the +help() window Keyboard tab. See the keyboardAndMouse example for an +illustration. + +CGAL_INLINE_FUNCTION +See also QOpenGLWidget::keyReleaseEvent(). */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::keyPressEvent(QKeyEvent *e) { + if (e->key() == 0) { + e->ignore(); + return; + } + + const ::Qt::Key key = ::Qt::Key(e->key()); + + const ::Qt::KeyboardModifiers modifiers = e->modifiers(); + + QMap::ConstIterator it = keyboardBinding_ + .begin(), + end = + keyboardBinding_.end(); + const unsigned int target = key | modifiers; + while ((it != end) && (it.value() != target)) + ++it; + + if (it != end) + handleKeyboardAction(it.key()); + else if (pathIndex_.contains(::Qt::Key(key))) { + // Camera paths + unsigned int index = pathIndex_[::Qt::Key(key)]; + + // not safe, but try to double press on two viewers at the same time ! + static QTime doublePress; + + if (modifiers == playPathKeyboardModifiers()) { + int elapsed = doublePress.restart(); + if ((elapsed < 250) && (index == previousPathId_)) + camera()->resetPath(index); + else { + // Stop previous interpolation before starting a new one. + if (index != previousPathId_) { + qglviewer::KeyFrameInterpolator *previous = + camera()->keyFrameInterpolator(previousPathId_); + if ((previous) && (previous->interpolationIsStarted())) + previous->resetInterpolation(); + } + camera()->playPath(index); + } + previousPathId_ = index; + } else if (modifiers == addKeyFrameKeyboardModifiers()) { + int elapsed = doublePress.restart(); + if ((elapsed < 250) && (index == previousPathId_)) { + if (camera()->keyFrameInterpolator(index)) { + disconnect(camera()->keyFrameInterpolator(index), + SIGNAL(interpolated()), this, SLOT(update())); + if (camera()->keyFrameInterpolator(index)->numberOfKeyFrames() > 1) + displayMessage( + tr("Path %1 deleted", "Feedback message").arg(index)); + else + displayMessage( + tr("Position %1 deleted", "Feedback message").arg(index)); + camera()->deletePath(index); + } + } else { + bool nullBefore = (camera()->keyFrameInterpolator(index) == NULL); + camera()->addKeyFrameToPath(index); + if (nullBefore) + connect(camera()->keyFrameInterpolator(index), SIGNAL(interpolated()), + SLOT(update())); + int nbKF = camera()->keyFrameInterpolator(index)->numberOfKeyFrames(); + if (nbKF > 1) + displayMessage(tr("Path %1, position %2 added", "Feedback message") + .arg(index) + .arg(nbKF)); + else + displayMessage( + tr("Position %1 saved", "Feedback message").arg(index)); + } + previousPathId_ = index; + } + update(); + } else { + if (isValidShortcutKey(key)) + currentlyPressedKey_ = key; + e->ignore(); + } +} + +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::keyReleaseEvent(QKeyEvent *e) { + if (isValidShortcutKey(e->key())) + currentlyPressedKey_ = ::Qt::Key(0); +} + +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::handleKeyboardAction(qglviewer::KeyboardAction id) { + switch (id) { + case qglviewer::DRAW_AXIS: + toggleAxisIsDrawn(); + break; + case qglviewer::DRAW_GRID: + toggleGridIsDrawn(); + break; + case qglviewer::DISPLAY_FPS: + toggleFPSIsDisplayed(); + break; + case qglviewer::ENABLE_TEXT: + toggleTextIsEnabled(); + break; + case qglviewer::EXIT_VIEWER: + saveStateToFileForAllViewers(); + qApp->closeAllWindows(); + break; + case qglviewer::FULL_SCREEN: + toggleFullScreen(); + break; + case qglviewer::STEREO: + toggleStereoDisplay(); + break; + case qglviewer::ANIMATION: + toggleAnimation(); + break; + case qglviewer::HELP: + help(); + break; + case qglviewer::EDIT_CAMERA: + toggleCameraIsEdited(); + break; + case qglviewer::CAMERA_MODE: + toggleCameraMode(); + displayMessage(cameraIsInRotateMode() + ? tr("Camera in observer mode", "Feedback message") + : tr("Camera in fly mode", "Feedback message")); + break; + + case qglviewer::MOVE_CAMERA_LEFT: + camera()->frame()->translate(camera()->frame()->inverseTransformOf( + qglviewer::Vec(-10.0 * camera()->flySpeed(), 0.0, 0.0))); + update(); + break; + case qglviewer::MOVE_CAMERA_RIGHT: + camera()->frame()->translate(camera()->frame()->inverseTransformOf( + qglviewer::Vec(10.0 * camera()->flySpeed(), 0.0, 0.0))); + update(); + break; + case qglviewer::MOVE_CAMERA_UP: + camera()->frame()->translate(camera()->frame()->inverseTransformOf( + qglviewer::Vec(0.0, 10.0 * camera()->flySpeed(), 0.0))); + update(); + break; + case qglviewer::MOVE_CAMERA_DOWN: + camera()->frame()->translate(camera()->frame()->inverseTransformOf( + qglviewer::Vec(0.0, -10.0 * camera()->flySpeed(), 0.0))); + update(); + break; + + case qglviewer::INCREASE_FLYSPEED: + camera()->setFlySpeed(camera()->flySpeed() * 1.5); + break; + case qglviewer::DECREASE_FLYSPEED: + camera()->setFlySpeed(camera()->flySpeed() / 1.5); + break; + } +} + +/*! Callback method used when the widget size is modified. + +If you overload this method, first call the inherited method. Also called when +the widget is created, before its first display. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::resizeGL(int width, int height) { + QOpenGLWidget::resizeGL(width, height); + glViewport(0, 0, GLint(width), GLint(height)); + camera()->setScreenWidthAndHeight(this->width(), this->height()); +} + +////////////////////////////////////////////////////////////////////////// +// K e y b o a r d s h o r t c u t s // +////////////////////////////////////////////////////////////////////////// + +/*! Defines the shortcut() that triggers a given CGAL::QGLViewer::KeyboardAction. + +Here are some examples: +\code +// Press 'Q' to exit application +setShortcut(EXIT_VIEWER, ::Qt::Key_Q); + +// Alt+M toggles camera mode +setShortcut(CAMERA_MODE, ::Qt::ALT + ::Qt::Key_M); + +// The DISPLAY_FPS action is disabled +setShortcut(DISPLAY_FPS, 0); +\endcode + +Only one shortcut can be assigned to a given CGAL::QGLViewer::KeyboardAction (new +bindings replace previous ones). If several KeyboardAction are binded to the +same shortcut, only one of them is active. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setShortcut(qglviewer::KeyboardAction action, unsigned int key) { + keyboardBinding_[action] = key; +} + +/*! Returns the keyboard shortcut associated to a given +CGAL::QGLViewer::KeyboardAction. + +Result is an \c unsigned \c int defined using Qt enumerated values, as in \c +::Qt::Key_Q or \c ::Qt::CTRL + ::Qt::Key_X. Use ::Qt::MODIFIER_MASK to separate the key +from the state keys. Returns \c 0 if the KeyboardAction is disabled (not +binded). Set using setShortcut(). + +If you want to define keyboard shortcuts for custom actions (say, open a scene +file), overload keyPressEvent() and then setKeyDescription(). + +These shortcuts and their descriptions are automatically included in the help() +window \c Keyboard tab. + +See the keyboard page for details and default +values and the keyboardAndMouse +example for a practical illustration. */ +CGAL_INLINE_FUNCTION +unsigned int CGAL::QGLViewer::shortcut(qglviewer::KeyboardAction action) const { + if (keyboardBinding_.contains(action)) + return keyboardBinding_[action]; + else + return 0; +} + + +/////// Key Frames associated keys /////// + +/*! Returns the keyboard key associated to camera Key Frame path \p index. + +Default values are F1..F12 for indexes 1..12. + +addKeyFrameKeyboardModifiers() (resp. playPathKeyboardModifiers()) define the +state key(s) that must be pressed with this key to add a KeyFrame to (resp. to +play) the associated Key Frame path. If you quickly press twice the pathKey(), +the path is reset (resp. deleted). + +Use camera()->keyFrameInterpolator( \p index ) to retrieve the +KeyFrameInterpolator that defines the path. + +If several keys are binded to a given \p index (see setPathKey()), one of them +is returned. Returns \c 0 if no key is associated with this index. + +See also the keyboard page. */ +CGAL_INLINE_FUNCTION +::Qt::Key CGAL::QGLViewer::pathKey(unsigned int index) const { + for (QMap< ::Qt::Key, unsigned int>::ConstIterator it = pathIndex_.begin(), + end = pathIndex_.end(); + it != end; ++it) + if (it.value() == index) + return it.key(); + return ::Qt::Key(0); +} + +/*! Sets the pathKey() associated with the camera Key Frame path \p index. + +Several keys can be binded to the same \p index. Use a negated \p key value to +delete the binding (the \p index value is then ignored): \code +// Press 'space' to play/pause/add/delete camera path of index 0. +setPathKey(::Qt::Key_Space, 0); + +// Remove this binding +setPathKey(-::Qt::Key_Space); +\endcode */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setPathKey(int key, unsigned int index) { + ::Qt::Key k = ::Qt::Key(abs(key)); + if (key < 0) + pathIndex_.remove(k); + else + pathIndex_[k] = index; +} + +/*! Sets the playPathKeyboardModifiers() value. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setPlayPathKeyboardModifiers(::Qt::KeyboardModifiers modifiers) { + playPathKeyboardModifiers_ = modifiers; +} + +/*! Sets the addKeyFrameKeyboardModifiers() value. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setAddKeyFrameKeyboardModifiers( + ::Qt::KeyboardModifiers modifiers) { + addKeyFrameKeyboardModifiers_ = modifiers; +} + +/*! Returns the keyboard modifiers that must be pressed with a pathKey() to add +the current camera position to a KeyFrame path. + +It can be \c ::Qt::NoModifier, \c ::Qt::ControlModifier, \c ::Qt::ShiftModifier, \c +::Qt::AltModifier, \c ::Qt::MetaModifier or a combination of these (using the +bitwise '|' operator). + +Default value is ::Qt::AltModifier. Defined using +setAddKeyFrameKeyboardModifiers(). + +See also playPathKeyboardModifiers(). */ +CGAL_INLINE_FUNCTION +::Qt::KeyboardModifiers CGAL::QGLViewer::addKeyFrameKeyboardModifiers() const { + return addKeyFrameKeyboardModifiers_; +} + +/*! Returns the keyboard modifiers that must be pressed with a pathKey() to play +a camera KeyFrame path. + +It can be \c ::Qt::NoModifier, \c ::Qt::ControlModifier, \c ::Qt::ShiftModifier, \c +::Qt::AltModifier, \c ::Qt::MetaModifier or a combination of these (using the +bitwise '|' operator). + +Default value is ::Qt::NoModifier. Defined using setPlayPathKeyboardModifiers(). + +See also addKeyFrameKeyboardModifiers(). */ +CGAL_INLINE_FUNCTION +::Qt::KeyboardModifiers CGAL::QGLViewer::playPathKeyboardModifiers() const { + return playPathKeyboardModifiers_; +} + + +//////////////////////////////////////////////////////////////////////////////// +// M o u s e b e h a v i o r s t a t e k e y s // +//////////////////////////////////////////////////////////////////////////////// + +/*! Defines a MouseAction binding. + + Same as calling setMouseBinding(::Qt::Key, ::Qt::KeyboardModifiers, + ::Qt::MouseButton, MouseHandler, MouseAction, bool), with a key value of + ::Qt::Key(0) (i.e. no regular extra key needs to be pressed to perform this + action). */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setMouseBinding(::Qt::KeyboardModifiers modifiers, + ::Qt::MouseButton button, qglviewer::MouseHandler handler, + qglviewer::MouseAction action, bool withConstraint) { + setMouseBinding(::Qt::Key(0), modifiers, button, handler, action, + withConstraint); +} + +/*! Associates a MouseAction to any mouse \p button, while keyboard \p modifiers +and \p key are pressed. The receiver of the mouse events is a MouseHandler +(CGAL::QGLViewer::CAMERA or CGAL::QGLViewer::FRAME). + +The parameters should read: when the mouse \p button is pressed, while the +keyboard \p modifiers and \p key are down, activate \p action on \p handler. Use +::Qt::NoModifier to indicate that no modifier key is needed, and a \p key value of +0 if no regular key has to be pressed (or simply use +setMouseBinding(::Qt::KeyboardModifiers, ::Qt::MouseButton, MouseHandler, +MouseAction, bool)). + +Use the '|' operator to combine modifiers: +\code +// The R key combined with the Left mouse button rotates the camera in the +screen plane. setMouseBinding(::Qt::Key_R, ::Qt::NoModifier, ::Qt::LeftButton, CAMERA, +SCREEN_ROTATE); + +// Alt + Shift and Left button rotates the manipulatedFrame(). +setMouseBinding(::Qt::AltModifier | ::Qt::ShiftModifier, ::Qt::LeftButton, FRAME, +ROTATE); \endcode + +If \p withConstraint is \c true (default), the possible +CGAL::qglviewer::Frame::constraint() of the associated Frame will be enforced during +motion. + +The list of all possible MouseAction, some binding examples and default bindings +are provided in the mouse page. + +See the keyboardAndMouse example +for an illustration. + +If no mouse button is specified, the binding is ignored. If an action was +previously associated with this keyboard and button combination, it is silently +overwritten (call mouseAction() before to check). + +To remove a specific mouse binding, use \p NO_MOUSE_ACTION as the \p action. + +See also setMouseBinding(::Qt::KeyboardModifiers, ::Qt::MouseButtons, ClickAction, +bool, int), setWheelBinding() and clearMouseBindings(). */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setMouseBinding(::Qt::Key key, ::Qt::KeyboardModifiers modifiers, + ::Qt::MouseButton button, qglviewer::MouseHandler handler, + qglviewer::MouseAction action, bool withConstraint) { + if ((handler == qglviewer::FRAME) && + ((action == qglviewer::MOVE_FORWARD) || (action == qglviewer::MOVE_BACKWARD) || + (action == qglviewer::ROLL) || (action == qglviewer::LOOK_AROUND) || + (action == qglviewer::ZOOM_ON_REGION))) { + qWarning("Cannot bind %s to FRAME", + mouseActionString(action).toLatin1().constData()); + return; + } + + if (button == ::Qt::NoButton) { + qWarning("No mouse button specified in setMouseBinding"); + return; + } + + MouseActionPrivate map; + map.handler = handler; + map.action = action; + map.withConstraint = withConstraint; + + MouseBindingPrivate mbp(modifiers, button, key); + if (action == qglviewer::NO_MOUSE_ACTION) + mouseBinding_.remove(mbp); + else + mouseBinding_.insert(mbp, map); + + ClickBindingPrivate cbp(modifiers, button, false, ::Qt::NoButton, key); + clickBinding_.remove(cbp); +} + + +/*! Defines a ClickAction binding. + + Same as calling setMouseBinding(::Qt::Key, ::Qt::KeyboardModifiers, + ::Qt::MouseButton, ClickAction, bool, ::Qt::MouseButtons), with a key value of + ::Qt::Key(0) (i.e. no regular key needs to be pressed to activate this action). + */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setMouseBinding(::Qt::KeyboardModifiers modifiers, + ::Qt::MouseButton button, qglviewer::ClickAction action, + bool doubleClick, + ::Qt::MouseButtons buttonsBefore) { + setMouseBinding(::Qt::Key(0), modifiers, button, action, doubleClick, + buttonsBefore); +} + +/*! Associates a ClickAction to a button and keyboard key and modifier(s) +combination. + +The parameters should read: when \p button is pressed, while the \p modifiers +and \p key keys are down, and possibly as a \p doubleClick, then perform \p +action. Use ::Qt::NoModifier to indicate that no modifier key is needed, and a \p +key value of 0 if no regular key has to be pressed (or simply use +setMouseBinding(::Qt::KeyboardModifiers, ::Qt::MouseButton, ClickAction, bool, +::Qt::MouseButtons)). + +If \p buttonsBefore is specified (valid only when \p doubleClick is \c true), +then this (or these) other mouse button(s) has (have) to be pressed \e before +the double click occurs in order to execute \p action. + +The list of all possible ClickAction, some binding examples and default bindings +are listed in the mouse page. See also the +setMouseBinding() documentation. + +See the keyboardAndMouse example +for an illustration. + +The binding is ignored if ::Qt::NoButton is specified as \p buttons. + +See also setMouseBinding(::Qt::KeyboardModifiers, ::Qt::MouseButtons, MouseHandler, +MouseAction, bool), setWheelBinding() and clearMouseBindings(). +*/ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setMouseBinding(::Qt::Key key, ::Qt::KeyboardModifiers modifiers, + ::Qt::MouseButton button, qglviewer::ClickAction action, + bool doubleClick, + ::Qt::MouseButtons buttonsBefore) { + if ((buttonsBefore != ::Qt::NoButton) && !doubleClick) { + qWarning("Buttons before is only meaningful when doubleClick is true in " + "setMouseBinding()."); + return; + } + + if (button == ::Qt::NoButton) { + qWarning("No mouse button specified in setMouseBinding"); + return; + } + + ClickBindingPrivate cbp(modifiers, button, doubleClick, buttonsBefore, key); + + // #CONNECTION performClickAction comment on NO_CLICK_ACTION + if (action == qglviewer::NO_CLICK_ACTION) + clickBinding_.remove(cbp); + else + clickBinding_.insert(cbp, action); + + if ((!doubleClick) && (buttonsBefore == ::Qt::NoButton)) { + MouseBindingPrivate mbp(modifiers, button, key); + mouseBinding_.remove(mbp); + } +} + +/*! Defines a mouse wheel binding. + + Same as calling setWheelBinding(::Qt::Key, ::Qt::KeyboardModifiers, MouseHandler, + MouseAction, bool), with a key value of ::Qt::Key(0) (i.e. no regular key needs + to be pressed to activate this action). */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setWheelBinding(::Qt::KeyboardModifiers modifiers, + qglviewer::MouseHandler handler, qglviewer::MouseAction action, + bool withConstraint) { + setWheelBinding(::Qt::Key(0), modifiers, handler, action, withConstraint); +} + +/*! Associates a MouseAction and a MouseHandler to a mouse wheel event. + +This method is very similar to setMouseBinding(), but specific to the wheel. + +In the current implementation only CGAL::QGLViewer::ZOOM can be associated with +CGAL::QGLViewer::FRAME, while CGAL::QGLViewer::CAMERA can receive CGAL::QGLViewer::ZOOM and +CGAL::QGLViewer::MOVE_FORWARD. + +The difference between CGAL::QGLViewer::ZOOM and CGAL::QGLViewer::MOVE_FORWARD is that +CGAL::QGLViewer::ZOOM speed depends on the distance to the object, while +CGAL::QGLViewer::MOVE_FORWARD moves at a constant speed defined by +CGAL::qglviewer::Camera::flySpeed(). */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setWheelBinding(::Qt::Key key, ::Qt::KeyboardModifiers modifiers, + qglviewer::MouseHandler handler, qglviewer::MouseAction action, + bool withConstraint) { + //#CONNECTION# ManipulatedFrame::wheelEvent and + // ManipulatedCameraFrame::wheelEvent switches + if ((action != qglviewer::ZOOM) && (action != qglviewer::MOVE_FORWARD) && + (action != qglviewer::MOVE_BACKWARD) && (action != qglviewer::NO_MOUSE_ACTION)) { + qWarning("Cannot bind %s to wheel", + mouseActionString(action).toLatin1().constData()); + return; + } + + if ((handler == qglviewer::FRAME) && (action != qglviewer::ZOOM) && (action != qglviewer::NO_MOUSE_ACTION)) { + qWarning("Cannot bind %s to FRAME wheel", + mouseActionString(action).toLatin1().constData()); + return; + } + + MouseActionPrivate map; + map.handler = handler; + map.action = action; + map.withConstraint = withConstraint; + + WheelBindingPrivate wbp(modifiers, key); + if (action == qglviewer::NO_MOUSE_ACTION) + wheelBinding_.remove(wbp); + else + wheelBinding_[wbp] = map; +} + +/*! Clears all the default mouse bindings. + +After this call, you will have to use setMouseBinding() and setWheelBinding() to +restore the mouse bindings you are interested in. +*/ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::clearMouseBindings() { + mouseBinding_.clear(); + clickBinding_.clear(); + wheelBinding_.clear(); +} + +/*! Clears all the default keyboard shortcuts. + +After this call, you will have to use setShortcut() to define your own keyboard +shortcuts. +*/ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::clearShortcuts() { + keyboardBinding_.clear(); + pathIndex_.clear(); +} + +/*! Returns the MouseAction the will be triggered when the mouse \p button is +pressed, while the keyboard \p modifiers and \p key are pressed. + +Returns CGAL::QGLViewer::NO_MOUSE_ACTION if no action is associated with this +combination. Use 0 for \p key to indicate that no regular key needs to be +pressed. + +For instance, to know which motion corresponds to Alt+LeftButton, do: +\code +MouseAction ma = mouseAction(0, ::Qt::AltModifier, ::Qt::LeftButton); +if (ma != CGAL::QGLViewer::NO_MOUSE_ACTION) ... +\endcode + +Use mouseHandler() to know which object (CGAL::QGLViewer::CAMERA or CGAL::QGLViewer::FRAME) +will execute this action. */ +CGAL_INLINE_FUNCTION +qglviewer::MouseAction CGAL::QGLViewer::mouseAction(::Qt::Key key, + ::Qt::KeyboardModifiers modifiers, + ::Qt::MouseButton button) const { + MouseBindingPrivate mbp(modifiers, button, key); + if (mouseBinding_.contains(mbp)) + return mouseBinding_[mbp].action; + else + return qglviewer::NO_MOUSE_ACTION; +} + + +/*! Returns the MouseHandler which will be activated when the mouse \p button is +pressed, while the \p modifiers and \p key are pressed. + +If no action is associated with this combination, returns \c -1. Use 0 for \p +key and ::Qt::NoModifier for \p modifiers to represent the lack of a key press. + +For instance, to know which handler receives the Alt+LeftButton, do: +\code +int mh = mouseHandler(0, ::Qt::AltModifier, ::Qt::LeftButton); +if (mh == CGAL::QGLViewer::CAMERA) ... +\endcode + +Use mouseAction() to know which action (see the MouseAction enum) will be +performed on this handler. */ +CGAL_INLINE_FUNCTION +int CGAL::QGLViewer::mouseHandler(::Qt::Key key, ::Qt::KeyboardModifiers modifiers, + ::Qt::MouseButton button) const { + MouseBindingPrivate mbp(modifiers, button, key); + if (mouseBinding_.contains(mbp)) + return mouseBinding_[mbp].handler; + else + return -1; +} + + + +/*! Returns the keyboard state that triggers \p action on \p handler \p +withConstraint using the mouse wheel. + +If such a binding exists, results are stored in the \p key and \p modifiers +parameters. If the MouseAction \p action is not bound, \p key is set to the +illegal -1 value. If several keyboard states trigger the MouseAction, one of +them is returned. + +See also setMouseBinding(), getClickActionBinding() and getMouseActionBinding(). +*/ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::getWheelActionBinding(qglviewer::MouseHandler handler, qglviewer::MouseAction action, + bool withConstraint, ::Qt::Key &key, + ::Qt::KeyboardModifiers &modifiers) const { + for (QMap::ConstIterator + it = wheelBinding_.begin(), + end = wheelBinding_.end(); + it != end; ++it) + if ((it.value().handler == handler) && (it.value().action == action) && + (it.value().withConstraint == withConstraint)) { + key = it.key().key; + modifiers = it.key().modifiers; + return; + } + + key = ::Qt::Key_unknown; + modifiers = ::Qt::NoModifier; +} + +/*! Returns the mouse and keyboard state that triggers \p action on \p handler +\p withConstraint. + +If such a binding exists, results are stored in the \p key, \p modifiers and \p +button parameters. If the MouseAction \p action is not bound, \p button is set +to \c ::Qt::NoButton. If several mouse and keyboard states trigger the +MouseAction, one of them is returned. + +See also setMouseBinding(), getClickActionBinding() and getWheelActionBinding(). +*/ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::getMouseActionBinding(qglviewer::MouseHandler handler, qglviewer::MouseAction action, + bool withConstraint, ::Qt::Key &key, + ::Qt::KeyboardModifiers &modifiers, + ::Qt::MouseButton &button) const { + for (QMap::ConstIterator + it = mouseBinding_.begin(), + end = mouseBinding_.end(); + it != end; ++it) { + if ((it.value().handler == handler) && (it.value().action == action) && + (it.value().withConstraint == withConstraint)) { + key = it.key().key; + modifiers = it.key().modifiers; + button = it.key().button; + return; + } + } + + key = ::Qt::Key(0); + modifiers = ::Qt::NoModifier; + button = ::Qt::NoButton; +} + +/*! Returns the MouseAction (if any) that is performed when using the wheel, +when the \p modifiers and \p key keyboard keys are pressed. + +Returns NO_MOUSE_ACTION if no such binding has been defined using +setWheelBinding(). + +Same as mouseAction(), but for the wheel action. See also wheelHandler(). +*/ +qglviewer::MouseAction +CGAL_INLINE_FUNCTION +CGAL::QGLViewer::wheelAction(::Qt::Key key, ::Qt::KeyboardModifiers modifiers) const { + WheelBindingPrivate wbp(modifiers, key); + if (wheelBinding_.contains(wbp)) + return wheelBinding_[wbp].action; + else + return qglviewer::NO_MOUSE_ACTION; +} + +/*! Returns the MouseHandler (if any) that receives wheel events when the \p + modifiers and \p key keyboard keys are pressed. + + Returns -1 if no no such binding has been defined using setWheelBinding(). See + also wheelAction(). +*/ +CGAL_INLINE_FUNCTION +int CGAL::QGLViewer::wheelHandler(::Qt::Key key, + ::Qt::KeyboardModifiers modifiers) const { + WheelBindingPrivate wbp(modifiers, key); + if (wheelBinding_.contains(wbp)) + return wheelBinding_[wbp].handler; + else + return -1; +} + +/*! Same as mouseAction(), but for the ClickAction set using setMouseBinding(). + +Returns NO_CLICK_ACTION if no click action is associated with this keyboard and +mouse buttons combination. */ +CGAL_INLINE_FUNCTION +CGAL::qglviewer::ClickAction +CGAL::QGLViewer::clickAction(::Qt::Key key, ::Qt::KeyboardModifiers modifiers, + ::Qt::MouseButton button, bool doubleClick, + ::Qt::MouseButtons buttonsBefore) const { + ClickBindingPrivate cbp(modifiers, button, doubleClick, buttonsBefore, key); + if (clickBinding_.contains(cbp)) + return clickBinding_[cbp]; + else + return qglviewer::NO_CLICK_ACTION; +} + +/*! Returns the mouse and keyboard state that triggers \p action. + +If such a binding exists, results are stored in the \p key, \p modifiers, \p +button, \p doubleClick and \p buttonsBefore parameters. If the ClickAction \p +action is not bound, \p button is set to \c ::Qt::NoButton. If several mouse +buttons trigger in the ClickAction, one of them is returned. + +See also setMouseBinding(), getMouseActionBinding() and getWheelActionBinding(). +*/ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::getClickActionBinding(qglviewer::ClickAction action, ::Qt::Key &key, + ::Qt::KeyboardModifiers &modifiers, + ::Qt::MouseButton &button, + bool &doubleClick, + ::Qt::MouseButtons &buttonsBefore) const { + for (QMap::ConstIterator + it = clickBinding_.begin(), + end = clickBinding_.end(); + it != end; ++it) + if (it.value() == action) { + modifiers = it.key().modifiers; + button = it.key().button; + doubleClick = it.key().doubleClick; + buttonsBefore = it.key().buttonsBefore; + key = it.key().key; + return; + } + + modifiers = ::Qt::NoModifier; + button = ::Qt::NoButton; + doubleClick = false; + buttonsBefore = ::Qt::NoButton; + key = ::Qt::Key(0); +} + +/*! This function should be used in conjunction with toggleCameraMode(). It +returns \c true when at least one mouse button is binded to the \c ROTATE +mouseAction. This is crude way of determining which "mode" the camera is in. */ +CGAL_INLINE_FUNCTION +bool CGAL::QGLViewer::cameraIsInRotateMode() const { + //#CONNECTION# used in toggleCameraMode() and keyboardString() + ::Qt::Key key; + ::Qt::KeyboardModifiers modifiers; + ::Qt::MouseButton button; + getMouseActionBinding(qglviewer::CAMERA, qglviewer::ROTATE, true /*constraint*/, key, modifiers, + button); + return button != ::Qt::NoButton; +} + +/*! Swaps between two predefined camera mouse bindings. + +The first mode makes the camera observe the scene while revolving around the +CGAL::qglviewer::Camera::pivotPoint(). The second mode is designed for walkthrough +applications and simulates a flying camera. + +Practically, the three mouse buttons are respectively binded to: +\arg In rotate mode: CGAL::QGLViewer::ROTATE, CGAL::QGLViewer::ZOOM, CGAL::QGLViewer::TRANSLATE. +\arg In fly mode: CGAL::QGLViewer::MOVE_FORWARD, CGAL::QGLViewer::LOOK_AROUND, +CGAL::QGLViewer::MOVE_BACKWARD. + +The current mode is determined by checking if a mouse button is binded to +CGAL::QGLViewer::ROTATE for the CGAL::QGLViewer::CAMERA. The state key that was previously +used to move the camera is preserved. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::toggleCameraMode() { + ::Qt::Key key; + ::Qt::KeyboardModifiers modifiers; + ::Qt::MouseButton button; + getMouseActionBinding(qglviewer::CAMERA, qglviewer::ROTATE, true /*constraint*/, key, modifiers, + button); + bool rotateMode = button != ::Qt::NoButton; + + if (!rotateMode) { + getMouseActionBinding(qglviewer::CAMERA, qglviewer::MOVE_FORWARD, true /*constraint*/, key, + modifiers, button); + } + + //#CONNECTION# setDefaultMouseBindings() + if (rotateMode) { + camera()->frame()->updateSceneUpVector(); + camera()->frame()->stopSpinning(); + + setMouseBinding(modifiers, ::Qt::LeftButton, qglviewer::CAMERA, qglviewer::MOVE_FORWARD); + setMouseBinding(modifiers, ::Qt::MidButton, qglviewer::CAMERA, qglviewer::LOOK_AROUND); + setMouseBinding(modifiers, ::Qt::RightButton, qglviewer::CAMERA, qglviewer::MOVE_BACKWARD); + + 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::MidButton, qglviewer::NO_CLICK_ACTION, true); + setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, qglviewer::NO_CLICK_ACTION, true); + + setWheelBinding(modifiers, qglviewer::CAMERA, qglviewer::MOVE_FORWARD); + } else { + // Should stop flyTimer. But unlikely and not easy. + setMouseBinding(modifiers, ::Qt::LeftButton, qglviewer::CAMERA, qglviewer::ROTATE); + setMouseBinding(modifiers, ::Qt::MidButton, qglviewer::CAMERA, qglviewer::ZOOM); + setMouseBinding(modifiers, ::Qt::RightButton, qglviewer::CAMERA, qglviewer::TRANSLATE); + + setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, qglviewer::CAMERA, + qglviewer::SCREEN_ROTATE); + + setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, qglviewer::ALIGN_CAMERA, true); + setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, qglviewer::SHOW_ENTIRE_SCENE, true); + setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, qglviewer::CENTER_SCENE, true); + + setWheelBinding(modifiers, qglviewer::CAMERA, qglviewer::ZOOM); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// M a n i p u l a t e d f r a m e s // +//////////////////////////////////////////////////////////////////////////////// + +/*! Sets the viewer's manipulatedFrame(). + +Several objects can be manipulated simultaneously, as is done the multiSelect example. + +Defining the \e own viewer's camera()->frame() as the manipulatedFrame() is +possible and will result in a classical camera manipulation. See the luxo example for an illustration. + +Note that a CGAL::qglviewer::ManipulatedCameraFrame can be set as the +manipulatedFrame(): it is possible to manipulate the camera of a first viewer in +a second viewer. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setManipulatedFrame(qglviewer::ManipulatedFrame *frame) { + if (manipulatedFrame()) { + manipulatedFrame()->stopSpinning(); + + if (manipulatedFrame() != camera()->frame()) { + disconnect(manipulatedFrame(), SIGNAL(manipulated()), this, + SLOT(update())); + disconnect(manipulatedFrame(), SIGNAL(spun()), this, SLOT(update())); + } + } + + manipulatedFrame_ = frame; + + manipulatedFrameIsACamera_ = + ((manipulatedFrame() != camera()->frame()) && + (dynamic_cast(manipulatedFrame()) != NULL)); + + if (manipulatedFrame()) { + // Prevent multiple connections, that would result in useless display + // updates + if (manipulatedFrame() != camera()->frame()) { + connect(manipulatedFrame(), SIGNAL(manipulated()), SLOT(update())); + connect(manipulatedFrame(), SIGNAL(spun()), SLOT(update())); + } + } +} + +#ifndef DOXYGEN +//////////////////////////////////////////////////////////////////////////////// +// V i s u a l H i n t s // +//////////////////////////////////////////////////////////////////////////////// +/*! Draws viewer related visual hints. + +CGAL_INLINE_FUNCTION +Displays the new CGAL::qglviewer::Camera::pivotPoint() when it is changed. See the mouse page for details. Also draws a line between +CGAL::qglviewer::Camera::pivotPoint() and mouse cursor when the camera is rotated +around the camera Z axis. + +See also setVisualHintsMask() and resetVisualHints(). The hint color is +foregroundColor(). + +\note These methods may become more interesting one day. The current design is +too limited and should be improved when other visual hints must be drawn. + +Limitation : One needs to have access to visualHint_ to overload this method. + +Removed from the documentation for this reason. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::drawVisualHints() { + // G r i d + rendering_program.bind(); + vaos[GRID].bind(); + QMatrix4x4 mvpMatrix; + double mat[16]; + camera()->getModelViewProjectionMatrix(mat); + for(int i=0; i < 16; i++) + { + mvpMatrix.data()[i] = (float)mat[i]; + } + QMatrix4x4 mvMatrix; + for(int i=0; i < 16; i++) + { + mvMatrix.data()[i] = float(camera()->orientation().inverse().matrix()[i]); + } + rendering_program.setUniformValue("mvp_matrix", mvpMatrix); + rendering_program.setUniformValue("color", QColor(::Qt::lightGray)); + glDrawArrays(GL_LINES, 0, static_cast(grid_size)); + vaos[GRID].release(); + rendering_program.release(); + + rendering_program_light.bind(); + vaos[GRID_AXIS].bind(); + + rendering_program_light.setUniformValue("mvp_matrix", mvpMatrix); + rendering_program_light.setUniformValue("mv_matrix", mvMatrix); + glDrawArrays(GL_TRIANGLES, 0, static_cast(g_axis_size/9)); + vaos[GRID_AXIS].release(); + glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(3.0f,-3.0f); + //A x i s + CGAL::qglviewer::Camera::Type camera_type = camera()->type(); + camera()->setType(CGAL::qglviewer::Camera::ORTHOGRAPHIC); + for(int i=0; i < 16; i++) + { + mvMatrix.data()[i] = float(camera()->orientation().inverse().matrix()[i]); + } + mvpMatrix.setToIdentity(); + mvpMatrix.ortho(-1,1,-1,1,-1,1); + mvpMatrix = mvpMatrix*mvMatrix; + rendering_program_light.setUniformValue("mvp_matrix", mvpMatrix); + rendering_program_light.setUniformValue("mv_matrix", mvMatrix); + camera()->setType(camera_type); + vaos[AXIS].bind(); + int viewport[4]; + int scissor[4]; + + // The viewport and the scissor are changed to fit the upper right + // corner. Original values are saved. + glGetIntegerv(GL_VIEWPORT, viewport); + glGetIntegerv(GL_SCISSOR_BOX, scissor); + + // Axis viewport size, in pixels + int size = 100; + glViewport(width()*devicePixelRatio()-size, height()*devicePixelRatio()-size, size, size); + glScissor (width()*devicePixelRatio()-size, height()*devicePixelRatio()-size, size, size); + glDrawArrays(GL_TRIANGLES, 0, static_cast(axis_size / 9)); + // The viewport and the scissor are restored. + glScissor(scissor[0],scissor[1],scissor[2],scissor[3]); + glViewport(viewport[0],viewport[1],viewport[2],viewport[3]); + vaos[AXIS].release(); + rendering_program_light.release(); + + //P i v o t - P o i n t + if (visualHint_ & 1) + { + std::vector vertices; + for(int i=0; i< 4; ++i) + { + float x = float(std::pow(-1, i)*(1-i/2)); + float y = float(std::pow(-1, i)*(i/2)); + vertices.push_back(x); + vertices.push_back(y); + vertices.push_back(0); + } + rendering_program.bind(); + vaos[PIVOT_POINT].bind(); + vbos[Pivot_point].bind(); + vbos[Pivot_point].allocate(vertices.data(),static_cast(vertices.size()*sizeof(float))); + rendering_program.enableAttributeArray("vertex"); + rendering_program.setAttributeBuffer("vertex",GL_FLOAT,0,3); + vbos[Pivot_point].release(); + mvpMatrix.setToIdentity(); + mvpMatrix.ortho(-1,1,-1,1,-1,1); + size=30*devicePixelRatio(); + rendering_program.setUniformValue("mvp_matrix", mvpMatrix); + glViewport(GLint((camera()->projectedCoordinatesOf(camera()->pivotPoint()).x-size/2)*devicePixelRatio()), + GLint((height() - camera()->projectedCoordinatesOf(camera()->pivotPoint()).y-size/2)*devicePixelRatio()), size, size); + glScissor (GLint((camera()->projectedCoordinatesOf(camera()->pivotPoint()).x-size/2)*devicePixelRatio()), + GLint((height() - camera()->projectedCoordinatesOf(camera()->pivotPoint()).y-size/2)*devicePixelRatio()), size, size); + rendering_program.setUniformValue("color", QColor(::Qt::black)); + glLineWidth(3.0); + glDrawArrays(GL_LINES, 0, static_cast(4)); + rendering_program.setUniformValue("color", QColor(::Qt::white)); + glLineWidth(3.0); + glDrawArrays(GL_LINES, 0, static_cast(4)); + glLineWidth(1.0); + // The viewport and the scissor are restored. + glScissor(scissor[0],scissor[1],scissor[2],scissor[3]); + glViewport(viewport[0],viewport[1],viewport[2],viewport[3]); + vaos[PIVOT_POINT].release(); + rendering_program.release(); + } + +} + +/*! Defines the mask that will be used to drawVisualHints(). The only available +mask is currently 1, corresponding to the display of the +CGAL::qglviewer::Camera::pivotPoint(). resetVisualHints() is automatically called +after \p delay milliseconds (default is 2 seconds). */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setVisualHintsMask(int mask, int delay) { + visualHint_ = visualHint_ | mask; + QTimer::singleShot(delay, this, SLOT(resetVisualHints())); +} + +/*! Reset the mask used by drawVisualHints(). Called by setVisualHintsMask() + * after 2 seconds to reset the display. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::resetVisualHints() { visualHint_ = 0; } +#endif + +//////////////////////////////////////////////////////////////////////////////// +// A x i s a n d G r i d d i s p l a y l i s t s // +//////////////////////////////////////////////////////////////////////////////// + +/*! Draws a 3D arrow between the 3D point \p from and the 3D point \p to. +\p data is filled with the three components of a point, then its normal, and then its color, which makes it filled like this: +[P1.x-P1.y-P1.z-N1.x-N1.y-N1.z-C1.r-C1.g-C1.b|P2.x-P2.y-P2.z-N2.x-N2.y-N2.z-C2.r-C2.g-C2.b|...] +*/ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::drawArrow(double r,double R, int prec, CGAL::qglviewer::Vec from, + CGAL::qglviewer::Vec to, CGAL::qglviewer::Vec color, + std::vector &data) { + using std::cos; + using std::sin; + using std::acos; + CGAL::qglviewer::Vec temp = to-from; + QVector3D dir = QVector3D(float(temp.x), float(temp.y), float(temp.z)); + QMatrix4x4 mat; + mat.setToIdentity(); + mat.translate(float(from.x), float(from.y), float(from.z)); + mat.scale(dir.length()); + dir.normalize(); + float angle = 0.0; + if(std::sqrt((dir.x()*dir.x()+dir.y()*dir.y())) > 1) + angle = 90.0f; + else + angle = float(acos(dir.y()/std::sqrt(dir.lengthSquared()))*180.0/CGAL_PI); + + QVector3D axis; + axis = QVector3D(dir.z(), 0, -dir.x()); + mat.rotate(angle, axis); + + //Head + const float Rf = static_cast(R); + for(int d = 0; d<360; d+= 360/prec) + { + float D = (float) (d * CGAL_PI / 180.); + float a = (float) std::atan(Rf / 0.33); + QVector4D p(0., 1., 0, 1.); + QVector4D n(Rf*sin(D), sin(a), Rf*cos(D), 1.); + QVector4D pR = mat*p; + QVector4D nR = mat*n; + + //point A1 + data.push_back(pR.x()); + data.push_back(pR.y()); + data.push_back(pR.z()); + data.push_back(nR.x()); + data.push_back(nR.y()); + data.push_back(nR.z()); + data.push_back((float)color.x); + data.push_back((float)color.y); + data.push_back((float)color.z); + + //point B1 + p = QVector4D(Rf*sin(D), 0.66f, Rf* cos(D), 1.f); + n = QVector4D(sin(D), sin(a), cos(D), 1.); + pR = mat*p; + nR = mat*n; + data.push_back(pR.x()); + data.push_back(pR.y()); + data.push_back(pR.z()); + data.push_back(nR.x()); + data.push_back(nR.y()); + data.push_back(nR.z()); + data.push_back((float)color.x); + data.push_back((float)color.y); + data.push_back((float)color.z); + //point C1 + D = float((d+360/prec)*CGAL_PI/180.0); + p = QVector4D(Rf* sin(D), 0.66f, Rf* cos(D), 1.f); + n = QVector4D(sin(D), sin(a), cos(D), 1.0); + pR = mat*p; + nR = mat*n; + + data.push_back(pR.x()); + data.push_back(pR.y()); + data.push_back(pR.z()); + data.push_back(nR.x()); + data.push_back(nR.y()); + data.push_back(nR.z()); + data.push_back((float)color.x); + data.push_back((float)color.y); + data.push_back((float)color.z); + + } + + //cylinder + //body of the cylinder + const float rf = static_cast(r); + for(int d = 0; d<360; d+= 360/prec) + { + //point A1 + float D = float(d*CGAL_PI/180.0); + QVector4D p(rf*sin(D), 0.66f, rf*cos(D), 1.f); + QVector4D n(sin(D), 0.f, cos(D), 1.f); + QVector4D pR = mat*p; + QVector4D nR = mat*n; + + data.push_back(pR.x()); + data.push_back(pR.y()); + data.push_back(pR.z()); + data.push_back(nR.x()); + data.push_back(nR.y()); + data.push_back(nR.z()); + data.push_back(float(color.x)); + data.push_back(float(color.y)); + data.push_back(float(color.z)); + //point B1 + p = QVector4D(rf * sin(D),0,rf*cos(D), 1.0); + n = QVector4D(sin(D), 0, cos(D), 1.0); + pR = mat*p; + nR = mat*n; + + + data.push_back(pR.x()); + data.push_back(pR.y()); + data.push_back(pR.z()); + data.push_back(nR.x()); + data.push_back(nR.y()); + data.push_back(nR.z()); + data.push_back(float(color.x)); + data.push_back(float(color.y)); + data.push_back(float(color.z)); + //point C1 + D = float((d+360/prec)*CGAL_PI/180.0); + p = QVector4D(rf * sin(D),0,rf*cos(D), 1.0); + n = QVector4D(sin(D), 0, cos(D), 1.0); + pR = mat*p; + nR = mat*n; + data.push_back(pR.x()); + data.push_back(pR.y()); + data.push_back(pR.z()); + data.push_back(nR.x()); + data.push_back(nR.y()); + data.push_back(nR.z()); + data.push_back(float(color.x)); + data.push_back(float(color.y)); + data.push_back(float(color.z)); + //point A2 + D = float((d+360/prec)*CGAL_PI/180.0); + + p = QVector4D(rf * sin(D),0,rf*cos(D), 1.0); + n = QVector4D(sin(D), 0, cos(D), 1.0); + pR = mat*p; + nR = mat*n; + data.push_back(pR.x()); + data.push_back(pR.y()); + data.push_back(pR.z()); + data.push_back(nR.x()); + data.push_back(nR.y()); + data.push_back(nR.z()); + data.push_back(float(color.x)); + data.push_back(float(color.y)); + data.push_back(float(color.z)); + //point B2 + p = QVector4D(rf * sin(D), 0.66f, rf*cos(D), 1.f); + n = QVector4D(sin(D), 0, cos(D), 1.0); + pR = mat*p; + nR = mat*n; + data.push_back(pR.x()); + data.push_back(pR.y()); + data.push_back(pR.z()); + data.push_back(nR.x()); + data.push_back(nR.y()); + data.push_back(nR.z()); + data.push_back(float(color.x)); + data.push_back(float(color.y)); + data.push_back(float(color.z)); + //point C2 + D = float(d*CGAL_PI/180.0); + p = QVector4D(rf * sin(D), 0.66f, rf*cos(D), 1.f); + n = QVector4D(sin(D), 0.f, cos(D), 1.f); + pR = mat*p; + nR = mat*n; + data.push_back(pR.x()); + data.push_back(pR.y()); + data.push_back(pR.z()); + data.push_back(nR.x()); + data.push_back(nR.y()); + data.push_back(nR.z()); + data.push_back(float(color.x)); + data.push_back(float(color.y)); + data.push_back(float(color.z)); + + } +} + +/*! Draws an XYZ axis, with a given size (default is 1.0). + +The axis orientation matches the current modelView matrix state: +three arrows (red, green and blue) of length \p length are drawn along the +positive X, Y and Z directions in the top right corner of the screen. +X arrow is red, Y arrow is green and Z arrow is blue.*/ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::drawAxis(qreal length) { + std::vector data; + data.resize(0); + drawArrow(0.06,0.12,10, CGAL::qglviewer::Vec(0,0,0),CGAL::qglviewer::Vec(length,0,0),CGAL::qglviewer::Vec(1,0,0), data); + drawArrow(0.06,0.12,10, CGAL::qglviewer::Vec(0,0,0),CGAL::qglviewer::Vec(0,length,0),CGAL::qglviewer::Vec(0,1,0), data); + drawArrow(0.06,0.12,10, CGAL::qglviewer::Vec(0,0,0),CGAL::qglviewer::Vec(0,0,length),CGAL::qglviewer::Vec(0,0,1), data); + rendering_program_light.bind(); + vaos[AXIS].bind(); + vbos[Axis].bind(); + vbos[Axis].allocate(data.data(), static_cast(data.size() * sizeof(float))); + rendering_program_light.enableAttributeArray("vertex"); + rendering_program_light.setAttributeBuffer("vertex",GL_FLOAT,0,3, + static_cast(9*sizeof(float))); + + rendering_program_light.enableAttributeArray("normal"); + rendering_program_light.setAttributeBuffer("normal",GL_FLOAT,3*sizeof(float),3, + static_cast(9*sizeof(float))); + + rendering_program_light.enableAttributeArray("colors"); + rendering_program_light.setAttributeBuffer("colors",GL_FLOAT,6*sizeof(float),3, + static_cast(9*sizeof(float))); + vbos[Axis].release(); + vaos[AXIS].release(); + axis_size = data.size(); + rendering_program_light.release(); +} + +/*! Draws a grid in the XY plane, centered on (0,0,0) (defined in the current +coordinate system). + +\p size (OpenGL units) and \p nbSubdivisions define its geometry.*/ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::drawGrid(qreal size, int nbSubdivisions) { + + //The Grid + std::vector v_Grid; + for (int i=0; i<=nbSubdivisions; ++i) + { + const float pos = float(size*(2.0*i/nbSubdivisions-1.0)); + v_Grid.push_back(pos); + v_Grid.push_back(float(-size)); + v_Grid.push_back(0.f); + + v_Grid.push_back(pos); + v_Grid.push_back(float(+size)); + v_Grid.push_back(0.f); + + v_Grid.push_back(float(-size)); + v_Grid.push_back(pos); + v_Grid.push_back(0.f); + + v_Grid.push_back( float(size)); + v_Grid.push_back( pos); + v_Grid.push_back( 0.f); + } + rendering_program.bind(); + vaos[GRID].bind(); + vbos[Grid].bind(); + vbos[Grid].allocate(v_Grid.data(),static_cast(v_Grid.size()*sizeof(float))); + rendering_program.enableAttributeArray("vertex"); + rendering_program.setAttributeBuffer("vertex",GL_FLOAT,0,3); + vbos[Grid].release(); + vaos[GRID].release(); + rendering_program.release(); + grid_size = v_Grid.size(); + + //The Axis + std::vector d_axis; + d_axis.resize(0); + //d_axis is filled by drawArrow always this way : V.x V.y V.z N.x N.y N.z C.r C.g C.b, so it is possible + //to use a single buffer with offset and stride + drawArrow(0.005*size,0.02*size,10, CGAL::qglviewer::Vec(0,0,0),CGAL::qglviewer::Vec(size,0,0),CGAL::qglviewer::Vec(1,0,0), d_axis); + drawArrow(0.005*size,0.02*size,10, CGAL::qglviewer::Vec(0,0,0),CGAL::qglviewer::Vec(0,size,0),CGAL::qglviewer::Vec(0,1,0), d_axis); + + rendering_program_light.bind(); + vaos[GRID_AXIS].bind(); + vbos[Grid_axis].bind(); + vbos[Grid_axis].allocate(d_axis.data(), static_cast(d_axis.size() * sizeof(float))); + rendering_program_light.enableAttributeArray("vertex"); + rendering_program_light.setAttributeBuffer("vertex",GL_FLOAT,0,3, + static_cast(9*sizeof(float))); + + rendering_program_light.enableAttributeArray("normal"); + rendering_program_light.setAttributeBuffer("normal",GL_FLOAT,3*sizeof(float),3, + static_cast(9*sizeof(float))); + + rendering_program_light.enableAttributeArray("colors"); + rendering_program_light.setAttributeBuffer("colors",GL_FLOAT,6*sizeof(float),3, + static_cast(9*sizeof(float))); + vbos[Grid_axis].release(); + + vaos[GRID_AXIS].release(); + rendering_program_light.release(); + + g_axis_size = d_axis.size(); +} + +//////////////////////////////////////////////////////////////////////////////// +// S t a t i c m e t h o d s : Q G L V i e w e r P o o l // +//////////////////////////////////////////////////////////////////////////////// + +/*! saveStateToFile() is called on all the CGAL::QGLViewers using the QGLViewerPool(). + */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::saveStateToFileForAllViewers() { + Q_FOREACH (CGAL::QGLViewer *viewer, CGAL::QGLViewer::QGLViewerPool()) { + if (viewer) + viewer->saveStateToFile(); + } +} + +////////////////////////////////////////////////////////////////////////// +// S a v e s t a t e b e t w e e n s e s s i o n s // +////////////////////////////////////////////////////////////////////////// + +/*! Returns the state file name. Default value is \c .qglviewer.xml. + +This is the name of the XML file where saveStateToFile() saves the viewer state +(camera state, widget geometry, display flags... see domElement()) on exit. Use +restoreStateFromFile() to restore this state later (usually in your init() +method). + +Setting this value to \c QString::null will disable the automatic state file +saving that normally occurs on exit. + +If more than one viewer are created by the application, this function will +return a numbered file name (as in ".qglviewer1.xml", ".qglviewer2.xml"... using +QGLViewer::QGLViewerIndex()) for extra viewers. Each viewer will then read back +its own information in restoreStateFromFile(), provided that the viewers are +created in the same order, which is usually the case. */ +CGAL_INLINE_FUNCTION +QString CGAL::QGLViewer::stateFileName() const { + QString name = stateFileName_; + + if (!name.isEmpty() && QGLViewer::QGLViewerIndex(this) > 0) { + QFileInfo fi(name); + if (fi.suffix().isEmpty()) + name += QString::number(QGLViewer::QGLViewerIndex(this)); + else + name = fi.absolutePath() + '/' + fi.completeBaseName() + + QString::number(QGLViewer::QGLViewerIndex(this)) + "." + + fi.suffix(); + } + + return name; +} + +/*! Saves in stateFileName() an XML representation of the CGAL::QGLViewer state, +obtained from domElement(). + +Use restoreStateFromFile() to restore this viewer state. + +This method is automatically called when a viewer is closed (using Escape or +using the window's upper right \c x close button). setStateFileName() to \c +QString::null to prevent this. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::saveStateToFile() { + QString name = stateFileName(); + + if (name.isEmpty()) + return; + + QFileInfo fileInfo(name); + + if (fileInfo.isDir()) { + QMessageBox::warning( + this, tr("Save to file error", "Message box window title"), + tr("State file name (%1) references a directory instead of a file.") + .arg(name)); + return; + } + + const QString dirName = fileInfo.absolutePath(); + if (!QFileInfo(dirName).exists()) { + QDir dir; + if (!(dir.mkdir(dirName))) { + QMessageBox::warning(this, + tr("Save to file error", "Message box window title"), + tr("Unable to create directory %1").arg(dirName)); + return; + } + } + + // Write the DOM tree to file + QFile f(name); + if (f.open(QIODevice::WriteOnly)) { + QTextStream out(&f); + QDomDocument doc("QGLVIEWER"); + doc.appendChild(domElement("CGAL::QGLViewer", doc)); + doc.save(out, 2); + f.flush(); + f.close(); + } else + QMessageBox::warning( + this, tr("Save to file error", "Message box window title"), + tr("Unable to save to file %1").arg(name) + ":\n" + f.errorString()); +} + +/*! Restores the CGAL::QGLViewer state from the stateFileName() file using +initFromDOMElement(). + +States are saved using saveStateToFile(), which is automatically called on +viewer exit. + +Returns \c true when the restoration is successful. Possible problems are an non +existing or unreadable stateFileName() file, an empty stateFileName() or an XML +syntax error. + +A manipulatedFrame() should be defined \e before calling this method, so that +its state can be restored. Initialization code put \e after this function will +override saved values: \code void Viewer::init() +{ +// Default initialization goes here (including the declaration of a possible +manipulatedFrame). + +if (!restoreStateFromFile()) +showEntireScene(); // Previous state cannot be restored: fit camera to scene. + +// Specific initialization that overrides file savings goes here. +} +\endcode */ +CGAL_INLINE_FUNCTION +bool CGAL::QGLViewer::restoreStateFromFile() { + QString name = stateFileName(); + + if (name.isEmpty()) + return false; + + QFileInfo fileInfo(name); + + if (!fileInfo.isFile()) + // No warning since it would be displayed at first start. + return false; + + if (!fileInfo.isReadable()) { + QMessageBox::warning( + this, tr("Problem in state restoration", "Message box window title"), + tr("File %1 is not readable.").arg(name)); + return false; + } + + // Read the DOM tree form file + QFile f(name); + if (f.open(QIODevice::ReadOnly)) { + QDomDocument doc; + doc.setContent(&f); + f.close(); + QDomElement main = doc.documentElement(); + initFromDOMElement(main); + } else { + QMessageBox::warning( + this, tr("Open file error", "Message box window title"), + tr("Unable to open file %1").arg(name) + ":\n" + f.errorString()); + return false; + } + + return true; +} + +/*! Returns an XML \c QDomElement that represents the CGAL::QGLViewer. + +Used by saveStateToFile(). restoreStateFromFile() uses initFromDOMElement() to +restore the CGAL::QGLViewer state from the resulting \c QDomElement. + +\p name is the name of the QDomElement tag. \p doc is the \c QDomDocument +factory used to create QDomElement. + +The created QDomElement contains state values (axisIsDrawn(), FPSIsDisplayed(), +isFullScreen()...), viewer geometry, as well as camera() (see +CGAL::qglviewer::Camera::domElement()) and manipulatedFrame() (if defined, see +CGAL::qglviewer::ManipulatedFrame::domElement()) states. + +Overload this method to add your own attributes to the state file: +\code +CGAL_INLINE_FUNCTION +QDomElement Viewer::domElement(const QString& name, QDomDocument& document) +const +{ +// Creates a custom node for a light +QDomElement de = document.createElement("Light"); +de.setAttribute("state", (lightIsOn()?"on":"off")); +// Note the include of the ManipulatedFrame domElement method. +de.appendChild(lightManipulatedFrame()->domElement("LightFrame", document)); + +// Get default state domElement and append custom node +CGAL_INLINE_FUNCTION +QDomElement res = CGAL::QGLViewer::domElement(name, document); +res.appendChild(de); +return res; +} +\endcode +See initFromDOMElement() for the associated restoration code. + +\attention For the manipulatedFrame(), CGAL::qglviewer::Frame::constraint() and +CGAL::qglviewer::Frame::referenceFrame() are not saved. See +CGAL::qglviewer::Frame::domElement(). */ +CGAL_INLINE_FUNCTION +QDomElement CGAL::QGLViewer::domElement(const QString &name, + QDomDocument &document) const { + QDomElement de = document.createElement(name); + + QDomElement stateNode = document.createElement("State"); + // hasMouseTracking() is not saved + stateNode.appendChild(DomUtils::QColorDomElement( + foregroundColor(), "foregroundColor", document)); + stateNode.appendChild(DomUtils::QColorDomElement( + backgroundColor(), "backgroundColor", document)); + DomUtils::setBoolAttribute(stateNode, "stereo", displaysInStereo()); + // Revolve or fly camera mode is not saved + de.appendChild(stateNode); + + QDomElement displayNode = document.createElement("Display"); + DomUtils::setBoolAttribute(displayNode, "axisIsDrawn", axisIsDrawn()); + DomUtils::setBoolAttribute(displayNode, "gridIsDrawn", gridIsDrawn()); + DomUtils::setBoolAttribute(displayNode, "FPSIsDisplayed", FPSIsDisplayed()); + DomUtils::setBoolAttribute(displayNode, "cameraIsEdited", cameraIsEdited()); + // textIsEnabled() is not saved + de.appendChild(displayNode); + + QDomElement geometryNode = document.createElement("Geometry"); + DomUtils::setBoolAttribute(geometryNode, "fullScreen", isFullScreen()); + if (isFullScreen()) { + geometryNode.setAttribute("prevPosX", QString::number(prevPos_.x())); + geometryNode.setAttribute("prevPosY", QString::number(prevPos_.y())); + } else { + QWidget *tlw = topLevelWidget(); + geometryNode.setAttribute("width", QString::number(tlw->width())); + geometryNode.setAttribute("height", QString::number(tlw->height())); + geometryNode.setAttribute("posX", QString::number(tlw->pos().x())); + geometryNode.setAttribute("posY", QString::number(tlw->pos().y())); + } + de.appendChild(geometryNode); + + // Restore original Camera zClippingCoefficient before saving. + if (cameraIsEdited()) + camera()->setZClippingCoefficient(previousCameraZClippingCoefficient_); + de.appendChild(camera()->domElement("Camera", document)); + if (cameraIsEdited()) + // #CONNECTION# 5.0 from setCameraIsEdited() + camera()->setZClippingCoefficient(5.0); + + if (manipulatedFrame()) + de.appendChild( + manipulatedFrame()->domElement("ManipulatedFrame", document)); + + return de; +} + +/*! Restores the CGAL::QGLViewer state from a \c QDomElement created by domElement(). + +Used by restoreStateFromFile() to restore the CGAL::QGLViewer state from a file. + +Overload this method to retrieve custom attributes from the CGAL::QGLViewer state +file. This code corresponds to the one given in the domElement() documentation: +\code +CGAL_INLINE_FUNCTION +void Viewer::initFromDOMElement(const QDomElement& element) +{ +// Restore standard state +CGAL_INLINE_FUNCTION +CGAL::QGLViewer::initFromDOMElement(element); + +QDomElement child=element.firstChild().toElement(); +while (!child.isNull()) +{ +if (child.tagName() == "Light") +{ +if (child.hasAttribute("state")) +setLightOn(child.attribute("state").toLower() == "on"); + +// Assumes there is only one child. Otherwise you need to parse child's children +recursively. QDomElement lf = child.firstChild().toElement(); if (!lf.isNull() +&& lf.tagName() == "LightFrame") +lightManipulatedFrame()->initFromDomElement(lf); +} +child = child.nextSibling().toElement(); +} +} +\endcode + +CGAL_INLINE_FUNCTION +See also CGAL::qglviewer::Camera::initFromDOMElement(), +CGAL::qglviewer::ManipulatedFrame::initFromDOMElement(). + +\note The manipulatedFrame() \e pointer is not modified by this method. If +defined, its state is simply set from the \p element values. */ +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::initFromDOMElement(const QDomElement &element) { + QDomElement child = element.firstChild().toElement(); + bool tmpCameraIsEdited = cameraIsEdited(); + while (!child.isNull()) { + if (child.tagName() == "State") { + // #CONNECTION# default values from defaultConstructor() + // setMouseTracking(DomUtils::boolFromDom(child, "mouseTracking", false)); + setStereoDisplay(DomUtils::boolFromDom(child, "stereo", false)); + // if ((child.attribute("cameraMode", "revolve") == "fly") && + // (cameraIsInRevolveMode())) toggleCameraMode(); + + QDomElement ch = child.firstChild().toElement(); + while (!ch.isNull()) { + if (ch.tagName() == "foregroundColor") + setForegroundColor(DomUtils::QColorFromDom(ch)); + if (ch.tagName() == "backgroundColor") + setBackgroundColor(DomUtils::QColorFromDom(ch)); + ch = ch.nextSibling().toElement(); + } + } + + if (child.tagName() == "Display") { + // #CONNECTION# default values from defaultConstructor() + setAxisIsDrawn(DomUtils::boolFromDom(child, "axisIsDrawn", false)); + setGridIsDrawn(DomUtils::boolFromDom(child, "gridIsDrawn", false)); + setFPSIsDisplayed(DomUtils::boolFromDom(child, "FPSIsDisplayed", false)); + // See comment below. + tmpCameraIsEdited = DomUtils::boolFromDom(child, "cameraIsEdited", false); + // setTextIsEnabled(DomUtils::boolFromDom(child, "textIsEnabled", true)); + } + + if (child.tagName() == "Geometry") { + setFullScreen(DomUtils::boolFromDom(child, "fullScreen", false)); + + if (isFullScreen()) { + prevPos_.setX(DomUtils::intFromDom(child, "prevPosX", 0)); + prevPos_.setY(DomUtils::intFromDom(child, "prevPosY", 0)); + } else { + int width = DomUtils::intFromDom(child, "width", 600); + int height = DomUtils::intFromDom(child, "height", 400); + topLevelWidget()->resize(width, height); + camera()->setScreenWidthAndHeight(this->width(), this->height()); + + QPoint pos; + pos.setX(DomUtils::intFromDom(child, "posX", 0)); + pos.setY(DomUtils::intFromDom(child, "posY", 0)); + topLevelWidget()->move(pos); + } + } + + if (child.tagName() == "Camera") { + connectAllCameraKFIInterpolatedSignals(false); + camera()->initFromDOMElement(child); + connectAllCameraKFIInterpolatedSignals(); + } + + if ((child.tagName() == "ManipulatedFrame") && (manipulatedFrame())) + manipulatedFrame()->initFromDOMElement(child); + + child = child.nextSibling().toElement(); + } + + // The Camera always stores its "real" zClippingCoef in domElement(). If it is + // edited, its "real" coef must be saved and the coef set to 5.0, as is done + // in setCameraIsEdited(). BUT : Camera and Display are read in an arbitrary + // order. We must initialize Camera's "real" coef BEFORE calling + // setCameraIsEdited. Hence this temp cameraIsEdited and delayed call + cameraIsEdited_ = tmpCameraIsEdited; + if (cameraIsEdited_) { + previousCameraZClippingCoefficient_ = camera()->zClippingCoefficient(); + // #CONNECTION# 5.0 from setCameraIsEdited. + camera()->setZClippingCoefficient(5.0); + } +} + + + +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::copyBufferToTexture(GLint , GLenum ) { +} + +/*! Returns the texture id of the texture created by copyBufferToTexture(). + +Use glBindTexture() to use this texture. Note that this is already done by +copyBufferToTexture(). + +Returns \c 0 is copyBufferToTexture() was never called or if the texure was +deleted using glDeleteTextures() since then. */ +CGAL_INLINE_FUNCTION +GLuint CGAL::QGLViewer::bufferTextureId() const { + return 0; +} + +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setOffset(CGAL::qglviewer::Vec offset) +{ + this->_offset = offset; +} + +CGAL_INLINE_FUNCTION +CGAL::qglviewer::Vec CGAL::QGLViewer::offset()const +{ + return _offset; +} + +CGAL_INLINE_FUNCTION +qreal CGAL::QGLViewer::sceneRadius() const { return camera()->sceneRadius(); } + +CGAL_INLINE_FUNCTION +CGAL::qglviewer::Vec CGAL::QGLViewer::sceneCenter() const { return camera()->sceneCenter(); } + +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setSceneRadius(qreal radius) { + camera()->setSceneRadius(radius); +} + +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setSceneCenter(const CGAL::qglviewer::Vec ¢er) { + camera()->setSceneCenter(center); +} + +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::setSceneBoundingBox(const CGAL::qglviewer::Vec &min, + const CGAL::qglviewer::Vec &max) { + camera()->setSceneBoundingBox(min + offset(), max + offset()); +} + +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::showEntireScene() { + camera()->showEntireScene(); + update(); +} + + +CGAL_INLINE_FUNCTION +QImage* CGAL::QGLViewer::takeSnapshot( CGAL::qglviewer::SnapShotBackground background_color, QSize finalSize, double oversampling, bool expand) +{ + makeCurrent(); + qreal aspectRatio = width() / static_cast(height()); + GLfloat alpha = 1.0f; + QColor previousBGColor = backgroundColor(); + switch(background_color) + { + case CGAL::qglviewer::CURRENT_BACKGROUND: + break; + case CGAL::qglviewer::TRANSPARENT_BACKGROUND: + setBackgroundColor(QColor(::Qt::transparent)); + alpha = 0.0f; + break; + case CGAL::qglviewer::CHOOSE_BACKGROUND: + QColor c = QColorDialog::getColor(); + if(c.isValid()) { + setBackgroundColor(c); + } + else + return NULL; + break; + } + + + QSize subSize(int(width()/oversampling), int(height()/oversampling)); + QSize size=QSize(width(), height()); + + + qreal newAspectRatio = finalSize.width() / static_cast(finalSize.height()); + + qreal zNear = camera()->zNear(); + qreal zFar = camera()->zFar(); + + qreal xMin, yMin; + + if(camera()->type()==CGAL::qglviewer::Camera::PERSPECTIVE) + { + if ((expand && (newAspectRatio>aspectRatio)) || (!expand && (newAspectRatiofieldOfView() / 2.0); + xMin = newAspectRatio * yMin; + } + else + { + xMin = zNear * tan(camera()->fieldOfView() / 2.0) * aspectRatio; + yMin = xMin / newAspectRatio; + } + } + else + { + double xy[6]; + camera()->getFrustum(xy); + if ((expand && (newAspectRatio>aspectRatio)) || (!expand && (newAspectRatioisNull()) + { + QMessageBox::warning(this, "Image saving error", + "Unable to create resulting image", + QMessageBox::Ok, QMessageBox::NoButton); + setBackgroundColor(previousBGColor); + return NULL; + } + + qreal scaleX = subSize.width() / static_cast(finalSize.width()); + qreal scaleY = subSize.height() / static_cast(finalSize.height()); + + qreal deltaX = 2.0 * xMin * scaleX; + qreal deltaY = 2.0 * yMin * scaleY; + + int nbX = finalSize.width() / subSize.width(); + int nbY = finalSize.height() / subSize.height(); + + // Extra subimage on the right/bottom border(s) if needed + if (nbX * subSize.width() < finalSize.width()) + nbX++; + if (nbY * subSize.height() < finalSize.height()) + nbY++; + GLdouble frustum[6]; + camera()->getFrustum(frustum); + QOpenGLFramebufferObject fbo(size, QOpenGLFramebufferObject::CombinedDepthStencil); + for (int i=0; isetFrustum(frustum); + preDraw(); + draw(); + fbo.release(); + + QImage snapshot = fbo.toImage(); + QImage subImage = snapshot.scaled(subSize, ::Qt::IgnoreAspectRatio, ::Qt::SmoothTransformation); + // Copy subImage in image + for (int ii=0; iiwidth()) + break; + for (int jj=0; jjheight()) + break; + image->setPixel(fi, fj, subImage.pixel(ii,jj)); + } + } + } + if(background_color !=0) + setBackgroundColor(previousBGColor); + camera()->setFrustum(frustum); + return image; +} + +CGAL_INLINE_FUNCTION +void CGAL::QGLViewer::saveSnapshot() +{ + qreal aspectRatio = width() / static_cast(height()); + static ImageInterface* imageInterface = NULL; + + if (!imageInterface) + imageInterface = new ImageInterface(this, aspectRatio); + + imageInterface->imgWidth->setValue(width()); + imageInterface->imgHeight->setValue(height()); + + if (imageInterface->exec() == QDialog::Rejected) + return; + QSize finalSize(imageInterface->imgWidth->value(), imageInterface->imgHeight->value()); + bool expand = imageInterface->expandFrustum->isChecked(); + QString fileName = QFileDialog::getSaveFileName(this, + tr("Save Snapshot"), "", tr("Image Files (*.png *.jpg *.bmp)")); + if(fileName.isEmpty()) + { + return; + } + QImage* image= takeSnapshot(static_cast(imageInterface->color_comboBox->currentIndex()), + finalSize, imageInterface->oversampling->value(), expand); + if(image) + { + image->save(fileName); + delete image; + } + +} + +} diff --git a/GraphicsView/include/CGAL/Qt/qglviewer_impl_list.h b/GraphicsView/include/CGAL/Qt/qglviewer_impl_list.h new file mode 100644 index 00000000000..ab8bd687080 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/qglviewer_impl_list.h @@ -0,0 +1,33 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 + +#ifndef QGLVIEWER_IMPL_LIST_H +#define QGLVIEWER_IMPL_LIST_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif diff --git a/GraphicsView/include/CGAL/Qt/quaternion.h b/GraphicsView/include/CGAL/Qt/quaternion.h new file mode 100644 index 00000000000..24577c2ec20 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/quaternion.h @@ -0,0 +1,340 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 + +#ifndef QGLVIEWER_QUATERNION_H +#define QGLVIEWER_QUATERNION_H +#include +#include +#include +#include +#include + +namespace CGAL{ +namespace qglviewer { +/*! \brief The Quaternion class represents 3D rotations and orientations. + \class Quaternion quaternion.h CGAL::QGLViewer/quaternion.h + + The Quaternion is an appropriate (although not very intuitive) + representation for 3D rotations and orientations. Many tools are provided to + ease the definition of a Quaternion: see constructors, setAxisAngle(), + setFromRotationMatrix(), setFromRotatedBasis(). + + You can apply the rotation represented by the Quaternion to 3D points + using rotate() and inverseRotate(). See also the Frame class that represents + a coordinate system and provides other conversion functions like + Frame::coordinatesOf() and Frame::transformOf(). + + You can apply the Quaternion \c q rotation to the OpenGL matrices using: + \code + glMultMatrixd(q.matrix()); + // equvalent to glRotate(q.angle()*180.0/M_PI, q.axis().x, q.axis().y, + q.axis().z); \endcode + + Quaternion is part of the \c qglviewer namespace, specify \c + Cgal::qglviewer::Quaternion or use the qglviewer namespace: \code using namespace + qglviewer; \endcode + +

Internal representation

+ + The internal representation of a Quaternion corresponding to a rotation + around axis \c axis, with an angle \c alpha is made of four qreals (i.e. + doubles) q[i]: \code {q[0],q[1],q[2]} = sin(alpha/2) * + {axis[0],axis[1],axis[2]} q[3] = cos(alpha/2) \endcode + + Note that certain implementations place the cosine term in first + position (instead of last here). + + The Quaternion is always normalized, so that its inverse() is actually + its conjugate. + + See also the Vec and Frame classes' documentations. + \nosubgrouping */ +class CGAL_QT_EXPORT Quaternion { +public: + /*! @name Defining a Quaternion */ + //@{ + /*! Default constructor, builds an identity rotation. */ + Quaternion() { + q[0] = q[1] = q[2] = 0.0; + q[3] = 1.0; + } + + /*! Constructor from rotation axis (non null) and angle (in radians). See also + * setAxisAngle(). */ + Quaternion(const Vec &axis, qreal angle) { setAxisAngle(axis, angle); } + + Quaternion(const Vec &from, const Vec &to); + + /*! Constructor from the four values of a Quaternion. First three values are + axis*sin(angle/2) and last one is cos(angle/2). + + \attention The identity Quaternion is Quaternion(0,0,0,1) and \e not + Quaternion(0,0,0,0) (which is not unitary). The default Quaternion() + creates such identity Quaternion. */ + Quaternion(qreal q0, qreal q1, qreal q2, qreal q3) { + q[0] = q0; + q[1] = q1; + q[2] = q2; + q[3] = q3; + } + + /*! Copy constructor. */ + Quaternion(const Quaternion &Q) { + for (int i = 0; i < 4; ++i) + q[i] = Q.q[i]; + } + + /*! Equal operator. */ + Quaternion &operator=(const Quaternion &Q) { + for (int i = 0; i < 4; ++i) + q[i] = Q.q[i]; + return (*this); + } + + /*! Sets the Quaternion as a rotation of axis \p axis and angle \p angle (in + radians). + + \p axis does not need to be normalized. A null \p axis will result in + an identity Quaternion. */ + void setAxisAngle(const Vec &axis, qreal angle) { + const qreal norm = axis.norm(); + if (norm < 1E-8) { + // Null rotation + q[0] = 0.0; + q[1] = 0.0; + q[2] = 0.0; + q[3] = 1.0; + } else { + const qreal sin_half_angle = sin(angle / 2.0); + q[0] = sin_half_angle * axis[0] / norm; + q[1] = sin_half_angle * axis[1] / norm; + q[2] = sin_half_angle * axis[2] / norm; + q[3] = cos(angle / 2.0); + } + } + + /*! Sets the Quaternion value. See the Quaternion(qreal, qreal, qreal, qreal) + * constructor documentation. */ + void setValue(qreal q0, qreal q1, qreal q2, qreal q3) { + q[0] = q0; + q[1] = q1; + q[2] = q2; + q[3] = q3; + } + +#ifndef DOXYGEN + void setFromRotatedBase(const Vec &X, const Vec &Y, const Vec &Z); +#endif + void setFromRotationMatrix(const qreal m[3][3]); + void setFromRotatedBasis(const Vec &X, const Vec &Y, const Vec &Z); + //@} + + /*! @name Accessing values */ + //@{ + Vec axis() const; + qreal angle() const; + void getAxisAngle(Vec &axis, qreal &angle) const; + + /*! Bracket operator, with a constant return value. \p i must range in [0..3]. + * See the Quaternion(qreal, qreal, qreal, qreal) documentation. */ + qreal operator[](int i) const { return q[i]; } + + /*! Bracket operator returning an l-value. \p i must range in [0..3]. See the + * Quaternion(qreal, qreal, qreal, qreal) documentation. */ + qreal &operator[](int i) { return q[i]; } + //@} + + /*! @name Rotation computations */ + //@{ + /*! Returns the composition of the \p a and \p b rotations. + + The order is important. When applied to a Vec \c v (see + operator*(const Quaternion&, const Vec&) and rotate()) the resulting + Quaternion acts as if \p b was applied first and then \p a was applied. + This is obvious since the image \c v' of \p v by the composited rotation + satisfies: \code v'= (a*b) * v = a * (b*v) \endcode + + Note that a*b usually differs from b*a. + + \attention For efficiency reasons, the resulting Quaternion is not + normalized. Use normalize() in case of numerical drift with small rotation + composition. */ + friend Quaternion operator*(const Quaternion &a, const Quaternion &b) { + return Quaternion( + a.q[3] * b.q[0] + b.q[3] * a.q[0] + a.q[1] * b.q[2] - a.q[2] * b.q[1], + a.q[3] * b.q[1] + b.q[3] * a.q[1] + a.q[2] * b.q[0] - a.q[0] * b.q[2], + a.q[3] * b.q[2] + b.q[3] * a.q[2] + a.q[0] * b.q[1] - a.q[1] * b.q[0], + a.q[3] * b.q[3] - b.q[0] * a.q[0] - a.q[1] * b.q[1] - a.q[2] * b.q[2]); + } + + /*! Quaternion rotation is composed with \p q. + + See operator*(), since this is equivalent to \c this = \c this * \p q. + + \note For efficiency reasons, the resulting Quaternion is not + normalized. You may normalize() it after each application in case of + numerical drift. */ + Quaternion &operator*=(const Quaternion &q) { + *this = (*this) * q; + return *this; + } + + /*! Returns the image of \p v by the rotation \p q. + + Same as q.rotate(v). See rotate() and inverseRotate(). */ + friend Vec operator*(const Quaternion &q, const Vec &v) { + return q.rotate(v); + } + + Vec rotate(const Vec &v) const; + Vec inverseRotate(const Vec &v) const; + //@} + + /*! @name Inversion */ + //@{ + /*! Returns the inverse Quaternion (inverse rotation). + + Result has a negated axis() direction and the same angle(). A + composition (see operator*()) of a Quaternion and its inverse() results in + an identity function. + + Use invert() to actually modify the Quaternion. */ + Quaternion inverse() const { return Quaternion(-q[0], -q[1], -q[2], q[3]); } + + /*! Inverses the Quaternion (same rotation angle(), but negated axis()). + + See also inverse(). */ + void invert() { + q[0] = -q[0]; + q[1] = -q[1]; + q[2] = -q[2]; + } + + /*! Negates all the coefficients of the Quaternion. + + This results in an other representation of the \e same rotation + (opposite rotation angle, but with a negated axis direction: the two cancel + out). However, note that the results of axis() and angle() are unchanged + after a call to this method since angle() always returns a value in [0,pi]. + + This method is mainly useful for Quaternion interpolation, so that the + spherical interpolation takes the shortest path on the unit sphere. See + slerp() for details. */ + void negate() { + invert(); + q[3] = -q[3]; + } + + /*! Normalizes the Quaternion coefficients. + + This method should not need to be called since we only deal with unit + Quaternions. This is however useful to prevent numerical drifts, especially + with small rotational increments. See also normalized(). */ + qreal normalize() { + const qreal norm = + sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]); + for (int i = 0; i < 4; ++i) + q[i] /= norm; + return norm; + } + + /*! Returns a normalized version of the Quaternion. + + See also normalize(). */ + Quaternion normalized() const { + qreal Q[4]; + const qreal norm = + sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]); + for (int i = 0; i < 4; ++i) + Q[i] = q[i] / norm; + return Quaternion(Q[0], Q[1], Q[2], Q[3]); + } + //@} + + /*! @name Associated matrix */ + //@{ + const GLdouble *matrix() const; + void getMatrix(GLdouble m[4][4]) const; + void getMatrix(GLdouble m[16]) const; + + void getRotationMatrix(qreal m[3][3]) const; + + const GLdouble *inverseMatrix() const; + void getInverseMatrix(GLdouble m[4][4]) const; + void getInverseMatrix(GLdouble m[16]) const; + + void getInverseRotationMatrix(qreal m[3][3]) const; + //@} + + /*! @name Slerp interpolation */ + //@{ + static Quaternion slerp(const Quaternion &a, const Quaternion &b, qreal t, + bool allowFlip = true); + static Quaternion squad(const Quaternion &a, const Quaternion &tgA, + const Quaternion &tgB, const Quaternion &b, qreal t); + /*! Returns the "dot" product of \p a and \p b: a[0]*b[0] + a[1]*b[1] + + * a[2]*b[2] + a[3]*b[3]. */ + static qreal dot(const Quaternion &a, const Quaternion &b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; + } + + Quaternion log(); + Quaternion exp(); + static Quaternion lnDif(const Quaternion &a, const Quaternion &b); + static Quaternion squadTangent(const Quaternion &before, + const Quaternion ¢er, + const Quaternion &after); + //@} + + /*! @name Random Quaternion */ + //@{ + static Quaternion randomQuaternion(); + //@} + + /*! @name XML representation */ + //@{ + explicit Quaternion(const QDomElement &element); + QDomElement domElement(const QString &name, QDomDocument &document) const; + void initFromDOMElement(const QDomElement &element); +//@} + +#ifdef DOXYGEN + /*! @name Output stream */ + //@{ + /*! Output stream operator. Enables debugging code like: + \code + Quaternion rot(...); + cout << "Rotation=" << rot << endl; + \endcode */ + std::ostream &operator<<(std::ostream &o, const CGAL::qglviewer::Vec &); +//@} +#endif + +private: + /*! The internal data representation is private, use operator[] to access + * values. */ + qreal q[4]; +}; + +}} // namespace CGAL::qglviewer + +std::ostream &operator<<(std::ostream &o, const CGAL::qglviewer::Quaternion &); + +#endif // QGLVIEWER_QUATERNION_H diff --git a/GraphicsView/include/CGAL/Qt/quaternion_impl.h b/GraphicsView/include/CGAL/Qt/quaternion_impl.h new file mode 100644 index 00000000000..5dd599da5d6 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/quaternion_impl.h @@ -0,0 +1,559 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 + +#ifdef CGAL_HEADER_ONLY +#define CGAL_INLINE_FUNCTION inline + +#include + +#else +#define CGAL_INLINE_FUNCTION +#endif +#include +#include +#include +#include // RAND_MAX + +// All the methods are declared inline in Quaternion.h +namespace CGAL{ +namespace qglviewer{ + + +/*! Constructs a Quaternion that will rotate from the \p from direction to the +\p to direction. + +Note that this rotation is not uniquely defined. The selected axis is usually +orthogonal to \p from and \p to, minimizing the rotation angle. This method is +robust and can handle small or almost identical vectors. */ +CGAL_INLINE_FUNCTION +Quaternion::Quaternion(const Vec &from, const Vec &to) { + const qreal epsilon = 1E-10; + + const qreal fromSqNorm = from.squaredNorm(); + const qreal toSqNorm = to.squaredNorm(); + // Identity Quaternion when one vector is null + if ((fromSqNorm < epsilon) || (toSqNorm < epsilon)) { + q[0] = q[1] = q[2] = 0.0; + q[3] = 1.0; + } else { + Vec axis = cross(from, to); + const qreal axisSqNorm = axis.squaredNorm(); + + // Aligned vectors, pick any axis, not aligned with from or to + if (axisSqNorm < epsilon) + axis = from.orthogonalVec(); + + qreal angle = asin(sqrt(axisSqNorm / (fromSqNorm * toSqNorm))); + + if (from * to < 0.0) + angle = CGAL_PI - angle; + + setAxisAngle(axis, angle); + } +} + +/*! Returns the image of \p v by the Quaternion inverse() rotation. + +rotate() performs an inverse transformation. Same as inverse().rotate(v). */ +CGAL_INLINE_FUNCTION +Vec Quaternion::inverseRotate(const Vec &v) const { + return inverse().rotate(v); +} + +/*! Returns the image of \p v by the Quaternion rotation. + +See also inverseRotate() and operator*(const Quaternion&, const Vec&). */ +CGAL_INLINE_FUNCTION +Vec Quaternion::rotate(const Vec &v) const { + const qreal q00 = 2.0 * q[0] * q[0]; + const qreal q11 = 2.0 * q[1] * q[1]; + const qreal q22 = 2.0 * q[2] * q[2]; + + const qreal q01 = 2.0 * q[0] * q[1]; + const qreal q02 = 2.0 * q[0] * q[2]; + const qreal q03 = 2.0 * q[0] * q[3]; + + const qreal q12 = 2.0 * q[1] * q[2]; + const qreal q13 = 2.0 * q[1] * q[3]; + + const qreal q23 = 2.0 * q[2] * q[3]; + + return Vec((1.0 - q11 - q22) * v[0] + (q01 - q23) * v[1] + (q02 + q13) * v[2], + (q01 + q23) * v[0] + (1.0 - q22 - q00) * v[1] + (q12 - q03) * v[2], + (q02 - q13) * v[0] + (q12 + q03) * v[1] + + (1.0 - q11 - q00) * v[2]); +} + +/*! Set the Quaternion from a (supposedly correct) 3x3 rotation matrix. + + The matrix is expressed in European format: its three \e columns are the + images by the rotation of the three vectors of an orthogonal basis. Note that + OpenGL uses a symmetric representation for its matrices. + + setFromRotatedBasis() sets a Quaternion from the three axis of a rotated + frame. It actually fills the three columns of a matrix with these rotated + basis vectors and calls this method. */ +CGAL_INLINE_FUNCTION +void Quaternion::setFromRotationMatrix(const qreal m[3][3]) { + // Compute one plus the trace of the matrix + const qreal onePlusTrace = 1.0 + m[0][0] + m[1][1] + m[2][2]; + + if (onePlusTrace > 1E-5) { + // Direct computation + const qreal s = sqrt(onePlusTrace) * 2.0; + q[0] = (m[2][1] - m[1][2]) / s; + q[1] = (m[0][2] - m[2][0]) / s; + q[2] = (m[1][0] - m[0][1]) / s; + q[3] = 0.25 * s; + } else { + // Computation depends on major diagonal term + if ((m[0][0] > m[1][1]) & (m[0][0] > m[2][2])) { + const qreal s = sqrt(1.0 + m[0][0] - m[1][1] - m[2][2]) * 2.0; + q[0] = 0.25 * s; + q[1] = (m[0][1] + m[1][0]) / s; + q[2] = (m[0][2] + m[2][0]) / s; + q[3] = (m[1][2] - m[2][1]) / s; + } else if (m[1][1] > m[2][2]) { + const qreal s = sqrt(1.0 + m[1][1] - m[0][0] - m[2][2]) * 2.0; + q[0] = (m[0][1] + m[1][0]) / s; + q[1] = 0.25 * s; + q[2] = (m[1][2] + m[2][1]) / s; + q[3] = (m[0][2] - m[2][0]) / s; + } else { + const qreal s = sqrt(1.0 + m[2][2] - m[0][0] - m[1][1]) * 2.0; + q[0] = (m[0][2] + m[2][0]) / s; + q[1] = (m[1][2] + m[2][1]) / s; + q[2] = 0.25 * s; + q[3] = (m[0][1] - m[1][0]) / s; + } + } + normalize(); +} + + +/*! Sets the Quaternion from the three rotated vectors of an orthogonal basis. + + The three vectors do not have to be normalized but must be orthogonal and + direct (X^Y=k*Z, with k>0). + + \code + Quaternion q; + q.setFromRotatedBasis(X, Y, Z); + // Now q.rotate(Vec(1,0,0)) == X and q.inverseRotate(X) == Vec(1,0,0) + // Same goes for Y and Z with Vec(0,1,0) and Vec(0,0,1). + \endcode + + See also setFromRotationMatrix() and Quaternion(const Vec&, const Vec&). */ +CGAL_INLINE_FUNCTION +void Quaternion::setFromRotatedBasis(const Vec &X, const Vec &Y, const Vec &Z) { + qreal m[3][3]; + qreal normX = X.norm(); + qreal normY = Y.norm(); + qreal normZ = Z.norm(); + + for (int i = 0; i < 3; ++i) { + m[i][0] = X[i] / normX; + m[i][1] = Y[i] / normY; + m[i][2] = Z[i] / normZ; + } + + setFromRotationMatrix(m); +} + +/*! Returns the axis vector and the angle (in radians) of the rotation + represented by the Quaternion. See the axis() and angle() documentations. */ +CGAL_INLINE_FUNCTION +void Quaternion::getAxisAngle(Vec &axis, qreal &angle) const { + angle = 2.0 * acos(q[3]); + axis = Vec(q[0], q[1], q[2]); + const qreal sinus = axis.norm(); + if (sinus > 1E-8) + axis /= sinus; + + if (angle > CGAL_PI) { + angle = 2.0 * qreal(CGAL_PI) - angle; + axis = -axis; + } +} + +/*! Returns the normalized axis direction of the rotation represented by the +Quaternion. + +It is null for an identity Quaternion. See also angle() and getAxisAngle(). */ +CGAL_INLINE_FUNCTION +Vec Quaternion::axis() const { + Vec res = Vec(q[0], q[1], q[2]); + const qreal sinus = res.norm(); + if (sinus > 1E-8) + res /= sinus; + return (acos(q[3]) <= CGAL_PI / 2.0) ? res : -res; +} + +/*! Returns the angle (in radians) of the rotation represented by the + Quaternion. + + This value is always in the range [0-pi]. Larger rotational angles are obtained + by inverting the axis() direction. + + See also axis() and getAxisAngle(). */ +CGAL_INLINE_FUNCTION +qreal Quaternion::angle() const { + const qreal angle = 2.0 * acos(q[3]); + return (angle <= CGAL_PI) ? angle : 2.0 * CGAL_PI - angle; +} + +/*! Returns an XML \c QDomElement that represents the Quaternion. + + \p name is the name of the QDomElement tag. \p doc is the \c QDomDocument + factory used to create QDomElement. + + When output to a file, the resulting QDomElement will look like: + \code + + \endcode + + Use initFromDOMElement() to restore the Quaternion state from the resulting \c + QDomElement. See also the Quaternion(const QDomElement&) constructor. + +CGAL_INLINE_FUNCTION + See the Vec::domElement() documentation for a complete QDomDocument creation + and saving example. + +CGAL_INLINE_FUNCTION + See also Frame::domElement(), Camera::domElement(), +CGAL_INLINE_FUNCTION + KeyFrameInterpolator::domElement()... */ +CGAL_INLINE_FUNCTION +QDomElement Quaternion::domElement(const QString &name, + QDomDocument &document) const { + QDomElement de = document.createElement(name); + de.setAttribute("q0", QString::number(q[0])); + de.setAttribute("q1", QString::number(q[1])); + de.setAttribute("q2", QString::number(q[2])); + de.setAttribute("q3", QString::number(q[3])); + return de; +} + +/*! Restores the Quaternion state from a \c QDomElement created by domElement(). + + The \c QDomElement should contain the \c q0, \c q1 , \c q2 and \c q3 + attributes. If one of these attributes is missing or is not a number, a warning + is displayed and these fields are respectively set to 0.0, 0.0, 0.0 and 1.0 + (identity Quaternion). + + See also the Quaternion(const QDomElement&) constructor. */ +CGAL_INLINE_FUNCTION +void Quaternion::initFromDOMElement(const QDomElement &element) { + Quaternion q(element); + *this = q; +} + +/*! Constructs a Quaternion from a \c QDomElement representing an XML code of + the form \code< anyTagName q0=".." q1=".." q2=".." q3=".." />\endcode + + If one of these attributes is missing or is not a number, a warning is + displayed and the associated value is respectively set to 0, 0, 0 and 1 + (identity Quaternion). + + See also domElement() and initFromDOMElement(). */ +CGAL_INLINE_FUNCTION +Quaternion::Quaternion(const QDomElement &element) { + QStringList attribute; + attribute << "q0" + << "q1" + << "q2" + << "q3"; + for (int i = 0; i < attribute.size(); ++i) + q[i] = DomUtils::qrealFromDom(element, attribute[i], ((i < 3) ? 0.0 : 1.0)); +} + +/*! Returns the Quaternion associated 4x4 OpenGL rotation matrix. + + Use \c glMultMatrixd(q.matrix()) to apply the rotation represented by + Quaternion \c q to the current OpenGL matrix. + + See also getMatrix(), getRotationMatrix() and inverseMatrix(). + + \attention The result is only valid until the next call to matrix(). Use it + immediately (as shown above) or consider using getMatrix() instead. + + \attention The matrix is given in OpenGL format (row-major order) and is the + transpose of the actual mathematical European representation. Consider using + getRotationMatrix() instead. */ +CGAL_INLINE_FUNCTION +const GLdouble *Quaternion::matrix() const { + static GLdouble m[4][4]; + getMatrix(m); + return (const GLdouble *)(m); +} + +/*! Fills \p m with the OpenGL representation of the Quaternion rotation. + +Use matrix() if you do not need to store this matrix and simply want to alter +the current OpenGL matrix. See also getInverseMatrix() and Frame::getMatrix(). +*/ +CGAL_INLINE_FUNCTION +void Quaternion::getMatrix(GLdouble m[4][4]) const { + const qreal q00 = 2.0 * q[0] * q[0]; + const qreal q11 = 2.0 * q[1] * q[1]; + const qreal q22 = 2.0 * q[2] * q[2]; + + const qreal q01 = 2.0 * q[0] * q[1]; + const qreal q02 = 2.0 * q[0] * q[2]; + const qreal q03 = 2.0 * q[0] * q[3]; + + const qreal q12 = 2.0 * q[1] * q[2]; + const qreal q13 = 2.0 * q[1] * q[3]; + + const qreal q23 = 2.0 * q[2] * q[3]; + + m[0][0] = 1.0 - q11 - q22; + m[1][0] = q01 - q23; + m[2][0] = q02 + q13; + + m[0][1] = q01 + q23; + m[1][1] = 1.0 - q22 - q00; + m[2][1] = q12 - q03; + + m[0][2] = q02 - q13; + m[1][2] = q12 + q03; + m[2][2] = 1.0 - q11 - q00; + + m[0][3] = 0.0; + m[1][3] = 0.0; + m[2][3] = 0.0; + + m[3][0] = 0.0; + m[3][1] = 0.0; + m[3][2] = 0.0; + m[3][3] = 1.0; +} + +/*! Same as getMatrix(), but with a \c GLdouble[16] parameter. See also + * getInverseMatrix() and Frame::getMatrix(). */ +CGAL_INLINE_FUNCTION +void Quaternion::getMatrix(GLdouble m[16]) const { + static GLdouble mat[4][4]; + getMatrix(mat); + int count = 0; + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 4; ++j) + m[count++] = mat[i][j]; +} + +/*! Fills \p m with the 3x3 rotation matrix associated with the Quaternion. + + See also getInverseRotationMatrix(). + + \attention \p m uses the European mathematical representation of the rotation + matrix. Use matrix() and getMatrix() to retrieve the OpenGL transposed + version. */ +CGAL_INLINE_FUNCTION +void Quaternion::getRotationMatrix(qreal m[3][3]) const { + static GLdouble mat[4][4]; + getMatrix(mat); + for (int i = 0; i < 3; ++i) + for (int j = 0; j < 3; ++j) + // Beware of transposition + m[i][j] = qreal(mat[j][i]); +} + +/*! Returns the associated 4x4 OpenGL \e inverse rotation matrix. This is simply + the matrix() of the inverse(). + + \attention The result is only valid until the next call to inverseMatrix(). + Use it immediately (as in \c glMultMatrixd(q.inverseMatrix())) or use + getInverseMatrix() instead. + + \attention The matrix is given in OpenGL format (row-major order) and is the + transpose of the actual mathematical European representation. Consider using + getInverseRotationMatrix() instead. */ +CGAL_INLINE_FUNCTION +const GLdouble *Quaternion::inverseMatrix() const { + static GLdouble m[4][4]; + getInverseMatrix(m); + return (const GLdouble *)(m); +} + +/*! Fills \p m with the OpenGL matrix corresponding to the inverse() rotation. + +Use inverseMatrix() if you do not need to store this matrix and simply want to +alter the current OpenGL matrix. See also getMatrix(). */ +CGAL_INLINE_FUNCTION +void Quaternion::getInverseMatrix(GLdouble m[4][4]) const { + inverse().getMatrix(m); +} + +/*! Same as getInverseMatrix(), but with a \c GLdouble[16] parameter. See also + * getMatrix(). */ +CGAL_INLINE_FUNCTION +void Quaternion::getInverseMatrix(GLdouble m[16]) const { + inverse().getMatrix(m); +} + +/*! \p m is set to the 3x3 \e inverse rotation matrix associated with the + Quaternion. + + \attention This is the classical mathematical rotation matrix. The OpenGL + format uses its transposed version. See inverseMatrix() and getInverseMatrix(). + */ +CGAL_INLINE_FUNCTION +void Quaternion::getInverseRotationMatrix(qreal m[3][3]) const { + static GLdouble mat[4][4]; + getInverseMatrix(mat); + for (int i = 0; i < 3; ++i) + for (int j = 0; j < 3; ++j) + // Beware of transposition + m[i][j] = qreal(mat[j][i]); +} + +/*! Returns the slerp interpolation of Quaternions \p a and \p b, at time \p t. + + \p t should range in [0,1]. Result is \p a when \p t=0 and \p b when \p t=1. + + When \p allowFlip is \c true (default) the slerp interpolation will always use + the "shortest path" between the Quaternions' orientations, by "flipping" the + source Quaternion if needed (see negate()). */ +CGAL_INLINE_FUNCTION +Quaternion Quaternion::slerp(const Quaternion &a, const Quaternion &b, qreal t, + bool allowFlip) { + qreal cosAngle = Quaternion::dot(a, b); + + qreal c1, c2; + // Linear interpolation for close orientations + if ((1.0 - fabs(cosAngle)) < 0.01) { + c1 = 1.0 - t; + c2 = t; + } else { + // Spherical interpolation + qreal angle = acos(fabs(cosAngle)); + qreal sinAngle = sin(angle); + c1 = sin(angle * (1.0 - t)) / sinAngle; + c2 = sin(angle * t) / sinAngle; + } + + // Use the shortest path + if (allowFlip && (cosAngle < 0.0)) + c1 = -c1; + + return Quaternion(c1 * a[0] + c2 * b[0], c1 * a[1] + c2 * b[1], + c1 * a[2] + c2 * b[2], c1 * a[3] + c2 * b[3]); +} + +/*! Returns the slerp interpolation of the two Quaternions \p a and \p b, at + time \p t, using tangents \p tgA and \p tgB. + + The resulting Quaternion is "between" \p a and \p b (result is \p a when \p + t=0 and \p b for \p t=1). + + Use squadTangent() to define the Quaternion tangents \p tgA and \p tgB. */ +CGAL_INLINE_FUNCTION +Quaternion Quaternion::squad(const Quaternion &a, const Quaternion &tgA, + const Quaternion &tgB, const Quaternion &b, + qreal t) { + Quaternion ab = Quaternion::slerp(a, b, t); + Quaternion tg = Quaternion::slerp(tgA, tgB, t, false); + return Quaternion::slerp(ab, tg, 2.0 * t * (1.0 - t), false); +} + +/*! Returns the logarithm of the Quaternion. See also exp(). */ +CGAL_INLINE_FUNCTION +Quaternion Quaternion::log() { + qreal len = sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2]); + + if (len < 1E-6) + return Quaternion(q[0], q[1], q[2], 0.0); + else { + qreal coef = acos(q[3]) / len; + return Quaternion(q[0] * coef, q[1] * coef, q[2] * coef, 0.0); + } +} + +/*! Returns the exponential of the Quaternion. See also log(). */ +CGAL_INLINE_FUNCTION +Quaternion Quaternion::exp() { + qreal theta = sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2]); + + if (theta < 1E-6) + return Quaternion(q[0], q[1], q[2], cos(theta)); + else { + qreal coef = sin(theta) / theta; + return Quaternion(q[0] * coef, q[1] * coef, q[2] * coef, cos(theta)); + } +} + +/*! Returns log(a. inverse() * b). Useful for squadTangent(). */ +CGAL_INLINE_FUNCTION +Quaternion Quaternion::lnDif(const Quaternion &a, const Quaternion &b) { + Quaternion dif = a.inverse() * b; + dif.normalize(); + return dif.log(); +} + +/*! Returns a tangent Quaternion for \p center, defined by \p before and \p + after Quaternions. + + Useful for smooth spline interpolation of Quaternion with squad() and slerp(). + */ +CGAL_INLINE_FUNCTION +Quaternion Quaternion::squadTangent(const Quaternion &before, + const Quaternion ¢er, + const Quaternion &after) { + Quaternion l1 = Quaternion::lnDif(center, before); + Quaternion l2 = Quaternion::lnDif(center, after); + Quaternion e; + for (int i = 0; i < 4; ++i) + e.q[i] = -0.25 * (l1.q[i] + l2.q[i]); + e = center * (e.exp()); + + // if (Quaternion::dot(e,b) < 0.0) + // e.negate(); + + return e; +} + +CGAL_INLINE_FUNCTION +std::ostream &operator<<(std::ostream &o, const Quaternion &Q) { + return o << Q[0] << '\t' << Q[1] << '\t' << Q[2] << '\t' << Q[3]; +} + +/*! Returns a random unit Quaternion. + +You can create a randomly directed unit vector using: +\code +CGAL_INLINE_FUNCTION +Vec randomDir = Quaternion::randomQuaternion() * Vec(1.0, 0.0, 0.0); // or any +other Vec \endcode + +\note This function uses rand() to create pseudo-random numbers and the random +number generator can be initialized using srand().*/ +CGAL_INLINE_FUNCTION +Quaternion Quaternion::randomQuaternion() { + // The rand() function is not very portable and may not be available on your + // system. Add the appropriate include or replace by an other random function + // in case of problem. + qreal seed = rand() / (qreal)RAND_MAX; + qreal r1 = sqrt(1.0 - seed); + qreal r2 = sqrt(seed); + qreal t1 = 2.0 * CGAL_PI * (rand() / (qreal)RAND_MAX); + qreal t2 = 2.0 * CGAL_PI * (rand() / (qreal)RAND_MAX); + return Quaternion(sin(t1) * r1, cos(t1) * r1, sin(t2) * r2, cos(t2) * r2); +} +}} diff --git a/Polyhedron/demo/Polyhedron/ImageInterface.ui b/GraphicsView/include/CGAL/Qt/resources/ImageInterface.ui similarity index 85% rename from Polyhedron/demo/Polyhedron/ImageInterface.ui rename to GraphicsView/include/CGAL/Qt/resources/ImageInterface.ui index 79b16b58a15..0dfa667b8a8 100644 --- a/Polyhedron/demo/Polyhedron/ImageInterface.ui +++ b/GraphicsView/include/CGAL/Qt/resources/ImageInterface.ui @@ -114,58 +114,6 @@ - - - - 6 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Image Quality - - - - - - - Between 0 (smallest files) and 100 (highest quality) - - - 0 - - - 100 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - diff --git a/GraphicsView/include/CGAL/Qt/resources/qglviewer-icon.xpm b/GraphicsView/include/CGAL/Qt/resources/qglviewer-icon.xpm new file mode 100644 index 00000000000..5c7e72a57e2 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/resources/qglviewer-icon.xpm @@ -0,0 +1,359 @@ +/* XPM */ +static const char * qglviewer_icon[] = { +"100 100 256 2", +" c None", +". c #0A0B27", +"+ c #090B2C", +"@ c #150C12", +"# c #080F34", +"$ c #1A0E1A", +"% c #220D0B", +"& c #260B0B", +"* c #230E1C", +"= c #12113E", +"- c #2C0D10", +"; c #2F0D09", +"> c #310D14", +", c #1A123A", +"' c #261025", +") c #17134B", +"! c #151453", +"~ c #1B1733", +"{ c #14135E", +"] c #281430", +"^ c #0E1867", +"/ c #3B1215", +"( c #32132A", +"_ c #1D1849", +": c #121C58", +"< c #431014", +"[ c #141974", +"} c #3A152E", +"| c #201A5E", +"1 c #1D204C", +"2 c #401431", +"3 c #261960", +"4 c #48171C", +"5 c #411B21", +"6 c #371B45", +"7 c #2A1C6B", +"8 c #0E229B", +"9 c #52171D", +"0 c #441A35", +"a c #1B2582", +"b c #65150F", +"c c #2D2076", +"d c #4D1B3A", +"e c #57182F", +"f c #3E1F54", +"g c #5E1924", +"h c #2E2567", +"i c #002BD1", +"j c #002AD9", +"k c #6D1A13", +"l c #36237A", +"m c #002FCD", +"n c #701A0D", +"o c #462060", +"p c #651C23", +"q c #322581", +"r c #552429", +"s c #581E41", +"t c #671E1B", +"u c #771911", +"v c #6C1B2B", +"w c #562341", +"x c #342A79", +"y c #3C2484", +"z c #062FE6", +"A c #68212B", +"B c #4D236B", +"C c #612045", +"D c #42267B", +"E c #811B10", +"F c #7C1E0E", +"G c #0033F1", +"H c #0032F9", +"I c #3A298E", +"J c #472872", +"K c #72202A", +"L c #4F2774", +"M c #652449", +"N c #442890", +"O c #1F37A8", +"P c #87200E", +"Q c #852014", +"R c #402B98", +"S c #6C244D", +"T c #7D2230", +"U c #8F1F12", +"V c #70254A", +"W c #542A7E", +"X c #212FF2", +"Y c #6E2E28", +"Z c #442E9B", +"` c #772834", +" . c #971E15", +".. c #552B86", +"+. c #693132", +"@. c #702A46", +"#. c #7B2645", +"$. c #862435", +"%. c #79264E", +"&. c #5A2B88", +"*. c #1B3AE9", +"=. c #9A2211", +"-. c #4E2EA0", +";. c #1E3BDE", +">. c #722F3D", +",. c #5E2C91", +"'. c #592F91", +"). c #7A322A", +"!. c #1D42D7", +"~. c #902539", +"{. c #7D2A52", +"]. c #862E26", +"^. c #822853", +"/. c #922B20", +"(. c #4E34AA", +"_. c #A62411", +":. c #5D309A", +"<. c #59387B", +"[. c #5631AB", +"}. c #5533A6", +"|. c #912840", +"1. c #8C2B3F", +"2. c #AE2215", +"3. c #862C57", +"4. c #5D32A8", +"5. c #882C53", +"6. c #5C34A2", +"7. c #6231A2", +"8. c #A32A18", +"9. c #5C398B", +"0. c #4D4480", +"a. c #982A3F", +"b. c #8D2B5A", +"c. c #962C44", +"d. c #902C56", +"e. c #7A3B43", +"f. c #3249C3", +"g. c #B42812", +"h. c #583E9B", +"i. c #BA2516", +"j. c #524297", +"k. c #55448B", +"l. c #5E3BA3", +"m. c #9E2C47", +"n. c #5A4676", +"o. c #873847", +"p. c #404E94", +"q. c #932F59", +"r. c #BE2810", +"s. c #992D5B", +"t. c #5941A4", +"u. c #8A3F36", +"v. c #9D2F58", +"w. c #78415D", +"x. c #A72D4D", +"y. c #A2304B", +"z. c #C72815", +"A. c #C12C13", +"B. c #654298", +"C. c #654780", +"D. c #8F385F", +"E. c #98345D", +"F. c #2F51E3", +"G. c #A93724", +"H. c #A0325B", +"I. c #CA2B10", +"J. c #A93054", +"K. c #A6305D", +"L. c #D42A00", +"M. c #D22914", +"N. c #89415D", +"O. c #6546A5", +"P. c #AB3255", +"Q. c #DC2806", +"R. c #A3355D", +"S. c #AA325A", +"T. c #A13F2F", +"U. c #6A4A8E", +"V. c #A53754", +"W. c #DE2A00", +"X. c #CF300A", +"Y. c #D62C0E", +"Z. c #A8385B", +"`. c #4B54C3", +" + c #964356", +".+ c #E82903", +"++ c #8F4757", +"@+ c #DF2C14", +"#+ c #D93011", +"$+ c #A23D62", +"%+ c #8C4E44", +"&+ c #E32F00", +"*+ c #6E4CA5", +"=+ c #6E4F9B", +"-+ c #A04259", +";+ c #9D4266", +">+ c #D03716", +",+ c #E3300D", +"'+ c #6A51A7", +")+ c #BA3F2F", +"!+ c #EC2E07", +"~+ c #A9405F", +"{+ c #EB2E13", +"]+ c #EF3100", +"^+ c #4A5CDC", +"/+ c #984A68", +"(+ c #B54536", +"_+ c #4563C9", +":+ c #F62E03", +"<+ c #EF310B", +"[+ c #E73411", +"}+ c #AA4B3E", +"|+ c #F62E10", +"1+ c #CE401F", +"2+ c #D33D23", +"3+ c #7455A7", +"4+ c #C54426", +"5+ c #A5496A", +"6+ c #F93106", +"7+ c #A45048", +"8+ c #CD412C", +"9+ c #F2350E", +"0+ c #AA4A64", +"a+ c #5266C7", +"b+ c #DE411E", +"c+ c #EF3C18", +"d+ c #755FAD", +"e+ c #C94C34", +"f+ c #C14F3F", +"g+ c #DB452E", +"h+ c #AB526E", +"i+ c #EB421F", +"j+ c #AA566A", +"k+ c #A55B6B", +"l+ c #AA5873", +"m+ c #E94824", +"n+ c #D94D35", +"o+ c #DB4F31", +"p+ c #5B71DE", +"q+ c #A85F76", +"r+ c #EC4C31", +"s+ c #E2522E", +"t+ c #E84F30", +"u+ c #CD5D42", +"v+ c #6976CD", +"w+ c #D9583F", +"x+ c #E55537", +"y+ c #E7573E", +"z+ c #D65F4C", +"A+ c #CA6457", +"B+ c #E35C3E", +"C+ c #D1634E", +"D+ c #E26447", +"E+ c #E1674E", +"F+ c #DE6F57", +"G+ c #DE705E", +" ", +" ", +" C+ ", +" ` >.o. 1+X.u+ ", +" e.A K K T $.T ++ 1+L.L.X. ", +" A A v ` T T T 1.~.++ X.L.L.L.W.1+ ", +" g A K K T T $.$.1.$.1. >+L.L.L.L.L.L. ", +" r g A v v T T $.1.$.$.|.|. + u+X.L.L.L.L.W.W.W.2+ ", +" f r g g K K v T T T |.|.1.1.c.-+ u+X.L.L.L.Q.L.Q.Q.W.W. ", +" 6 o B C. 4 9 p p v T T T 1.~.$.1.~.a.~.1. u+X.L.L.L.Q.L.W.L.W.W.W.o+ ", +" f o B C. 4 9 9 g v v T T $.1.1.~.|.c.c.c.m. 4+L.L.L.Q.L.Q.Q.W.&+W.W.,+b+ ", +" f o J L U. 9 9 A v K T $.1.1.$.|.|.c.c.c.a.a.q+ 4+L.L.L.L.L.Q.W.W.&+L.&+&+&+W. ", +" f o B W L <. < 9 g A e.` ` $.$.|.$.1.~.a.a.c.c.a.k+ 1+L.L.Q.Q.W.L.W.L.&+&+&+,+&+&+w+ ", +" 6 f B L L .. 4 4 9 o.$.|.$.c.a.c.c.m.m.y.c.q+ u+L.W.Q.L.W.&+&+W.&+,+&+&+&+.+s+ ", +" p. f o L W W .. / < r 1.|.|.c.c.c.c.y.m.y.a.k+ X.L.W.L.,+,+&+,+&+&+&+[+&+&+b+ ", +" 3 6 B L W W &.9. / o.|.|.c.a.m.y.a.a.y.y.q+ e+W.W.&+W.W.,+&+&+&+&+.+&+!+b+ ", +" a : f o L L ....&.B. / ++a.a.m.c.a.y.y.a.y.y.q+ u+W.W.W.&+.+&+{+&+[+&+!+&+]+&+ ", +" O ^ 1 f J W ....&.'.U. / 5 k+c.m.c.m.y.m.y.y.y.y. L.&+&+&+&+&+&+!+]+!+[+!+!+!+ ", +" f.[ ) $ <.L W ..&.'.'. / k+c.m.a.m.y.a.y.y.y.y. b+&+,+&+.+&+&+&+[+]+&+!+&+!+E+ ", +" `.8 ! = $ <.W ..&.'.'.B. - k+y.a.y.y.a.y.x.y.x.V. b+.+&+!+&+[+!+!+]+!+!+!+9+!+B+ ", +" a+m { = # $ ....'.'.'.,.=+ - k+m.y.y.y.V.y.x.y.x.V. w+!+&+!+]+&+[+&+!+[+<+!+]+&+B+ ", +" v+m 8 ) # $ U...'.'.'.,.:. - -+m.m.y.V.x.y.y.x.m.0+ s+&+!+[+&+!+]+<+!+]+]+[+<+9+B+ ", +" ;.m ) = + $ 9.&.'.l.l.,.*+ & -+y.y.x.x.J.x.y.x.y.0+ B+&+]+!+<+!+!+[+]+!+]+<+]+<+B+ ", +" ;.i [ = + . $ &.'.,.,.,.:.*+ & 0+y.y.x.y.y.y.J.V.x.l+ s+!+!+!+[+<+]+]+!+]+]+]+!+]+B+ ", +" ;.z ^+1 # + $ =+l.'.l.7.:.'. % y.x.y.x.x.P.y.x.P.y. B+.+[+]+!+[+]+]+<+]+]+]+]+<+B+ ", +" ;.z ;. + + . $ '.:.:.:.:.:.3+ & V.y.x.y.x.J.P.P.V.Z. x+<+]+]+]+:+]+]+]+9+<+9+9+]+ ", +" p+*.G G p+ + . @ U.:.:.7.:.6.7. % h+P.V.P.P.y.J.P.x.y.0+ s+]+9+]+]+9+9+]+]+]+]+]+9+<+ ", +" f. p+F.H H G F. . . . $ l.:.:.:.6.:.O. & 0+x.J.J.V.P.x.x.P.P.h+ x+<+]+<+]+]+]+9+]+]+]+9+]+<+ ", +" i G X X X G H ;. . . $ =+:.:.6.l.6.:.3+ % V.y.y.x.P.V.V.P.P.J. m+!+]+]+]+9+]+|+9+|+]+9+]+c+ ", +" m z G H G H G p+ . . * O.6.6.:.7.6.:. & V.P.P.P.x.P.P.V.V.V. i+]+]+<+|+:+]+]+:+]+:+:+]+m+ ", +" i z G G G G F. . . * 3+7.7.6.6.6.6.3+ % 0+x.P.x.V.x.x.x.x.P.0+ [+9+]+]+]+|+]+]+]+9+9+9+]+m+ ", +" i z G G H *. . . * :.6.6.7.6.7.:. & 0+P.P.P.P.P.P.P.P.V. :+:+]+]+9+]+9+9+|+:+:+:+]+B+ ", +" i z G G G p+ . * *+7.}.6.4.6.6.*+ % V.y.P.x.P.x.P.P.P.V. F+]+|+9+:+]+:+:+]+]+:+|+|+:+B+ ", +" i z G G ^+ . ' n.4.6.7.4.7.4.6. & 0+x.P.P.P.P.P.P.P.P.~+ s+9+]+:+]+|+6+]+]+|+9+]+]+9+ ", +" i z G F. . * O.4.6.6.6.6.4.*+ & ~+P.P.P.P.P.P.P.P.Z.l+ s+6+9+|+]+9+|+|+]+6+:+6+6+9+ ", +" j z !. . ] J 4.6.4.[.4.[.l. & P.P.P.P.P.P.P.P.P.V. c+9+6+]+|+6+9+]+6+9+|+9+|+i+ ", +" a+i ;. . ' l.[.(.6.6.6.4.*+ & h+P.P.S.P.S.P.P.P.P.0+ :+|+]+]+|+6+|+9+6+]+6+]+9+t+ ", +" a+!. . ] t.(.6.7.4.4.[.6. & S.P.P.P.P.P.S.S.S.S.q+ D+9+9+|+6+]+9+]+6+|+6+9+6+:+E+ ", +" . 3+7.[.6.(.6.6.6.*+ & h+S.S.P.S.~+P.P.P.P.~+ r+6+]+9+6+6+6+9+]+9+6+9+6+9+ ", +" . 6.(.6.4.4.4.(.6. & ~+P.P.P.P.P.P.P.P.P.h+ c+6+|+6+9+6+9+6+|+6+|+6+9+9+ ", +" . l.[.[.(.6.(.4.(.3+ % l+S.V.~+P.P.P.~+P.P.S. 9+]+|+6+9+6+|+9+9+]+|+6+9+t+ ", +" ~ *+(.6.4.4.4.6.4.l. % ~+P.S.P.S.P.S.P.S.S.0+ B+9+6+9+9+6+|+9+6+6+|+]+]+|+D+ ", +" ~ '+(.[.(.(.(.4.4.6.d+ & S.P.S.P.S.P.S.P.P.~+ i+9+6+6+9+6+6+:+9+:+6+|+6+c+ ", +" = '+(.[.(.(.[.4.[.(.O. % ~+~+S.Z.S.Z.S.P.Z.S.~+ 9+6+6+9+6+9+:+9+6+6+9+6+]+m+ ", +" _ '+Z }.}.4.6.(.(.[.4. & q+S.S.S.~+S.~+S.S.S.S.l+ x+]+9+6+9+6+9+6+9+9+6+9+|+6+B+ ", +" ) h h.Z -.-.}.(.(.[.[.(.'+ & R.Z.Z.S.S.S.S.~+Z.Z.R. r+|+6+|+6+9+6+|+6+6+9+6+9+]+F+ ", +" _ 3 x k.j.I Z -.Z Z }.4.(.(.4.t. % l+S.S.Z.Z.Z.S.S.S.S.Z.h+ F+]+9+6+9+6+9+6+9+9+6+9+6+6+c+ ", +" ) 3 7 q I I Z N }.}.}.(.}.}.(. & Z.Z.S.Z.Z.S.Z.Z.Z.Z.~+ B+6+6+9+6+|+6+9+6+6+|+6+6+9+y+ ", +" = ! 7 c q I N Z Z Z Z -.}.}.}.'+ % l+S.Z.S.S.Z.S.S.S.S.Z.h+ c+9+6+9+6+9+6+|+9+6+9+9+6+6+ ", +" _ ) 3 l q N N Z N -.}.Z -.(.O. & R.R.R.S.K.S.Z.Z.Z.V.$+ D+6+6+9+6+9+6+9+6+6+9+6+6+9+m+ ", +" _ 3 3 l q I N Z Z -.-.}.}.Z & $+S.S.Z.Z.Z.K.K.K.K.S.h+ i+9+6+9+6+9+6+9+9+6+9+9+6+9+B+ ", +" _ | 7 l y I I N N Z -.(.-.d+ % l+R.R.R.R.S.K.Z.S.S.S.~+ F+9+6+9+|+6+6+9+6+6+9+|+6+6+9+ ", +" _ 3 7 c q I R Z :.Z Z -.'+ & R.K.K.K.R.Z.S.Z.Z.Z.K.l+ r+9+6+6+9+6+6+6+9+6+6+9+9+6+t+ ", +" ) | 7 l y y I N R Z -.D & ;+R.Z.Z.S.K.K.R.Z.S.S.5+ G+6+6+9+9+6+9+9+9+6+6+9+6+6+]+E+ ", +" 3 x c I y I Z Z Z h.' & 5+K.K.R.R.S.K.S.K.R.R.S. t+9+6+|+9+6+6+6+6+9+6+9+|+|+i+ ", +" | c l q I R I Z h. $ & $+R.s.K.R.R.Z.R.K.K.K.5+ 9+6+9+6+6+6+c+6+9+6+9+|+6+6+x+ ", +" h 7 l q y N N j. * & H.H.R.s.K.H.H.K.Z.K.S.Z. r+9+6+9+6+6+6+6+6+6+6+9+9+9+c+ ", +" 0.l q y I y '+ ' ; ;+v.v.K.R.H.K.K.v.H.Z.R.5+ G+9+|+6+c+6+c+6+c+6+6+9+6+|+6+B+ ", +" 0.x D j. ' & ;+s.R.s.K.H.s.s.R.K.K.K.$+ m+9+9+|+9+6+9+6+6+c+6+6+9+9+6+ ", +" ( ( ; ;+v.$+s.R.v.H.R.K.K.R.s.R. E+9+|+9+6+6+c+6+c+6+6+9+9+6+6+t+ ", +" ( } & ; /+5.v.v.v.s.H.R.H.H.s.K.R.5+ i+9+|+9+9+6+6+6+c+6+6+6+9+6+9+ ", +" ( } - ; /+q.s.s.s.E.H.v.K.v.R.K.R.$+ y+|+|+9+9+|+9+c+6+6+c+9+9+|+9+x+ ", +" ( 2 0 - ; D.d.q.q.E.v.v.s.s.H.s.R.v.$+ 9+9+|+|+9+6+6+9+c+6+6+6+c+6+9+ ", +" } 0 0 ; ; 3.q.b.q.q.s.E.s.H.H.v.K.v.H.5+ r+9+|+9+9+6+c+9+6+6+c+9+9+|+|+x+ ", +" } 0 d d ; < N.5.3.q.q.q.q.s.E.E.E.s.v.s.H.5+ D+9+9+|+9+9+6+c+9+6+|+6+9+9+9+9+ ", +" } 2 s s s M w.w.e @.{.^.3.3.b.d.q.q.q.s.v.v.s.H.s.$+ i+9+|+9+|+c+6+|+6+9+9+9+9+6+|+y+ ", +" 0 0 d s C M V V V ^.^.5.5.5.3.d.q.q.q.q.s.v.E.R.E. r+9+c+|+9+|+9+c+c+|+|+9+6+9+6+i+ ", +" 2 2 s w C C V V %.{.{.5.b.5.q.3.d.q.q.s.E.E.v.s.q+ w+9+9+9+9+9+9+|+|+|+9+9+|+9+|+9+E+ ", +" 0 0 d w C C S V V {.%.#.3.5.d.d.d.q.q.s.s.E.E.q+ E+c+9+9+c+9+c+9+|+9+|+9+9+9+9+|+i+ ", +" } d s s C M V S %.%.^.3.3.3.3.3.d.d.q.d.q.s./+ i+!+c+9+9+9+|+9+9+|+9+|+9+|+|+9+G+ ", +" 0 d d e M M V S {.{.^.3.3.d.d.D.d.d.q.q.v./+ r+[+|+{+9+c+9+9+9+9+9+9+|+9+9+9+B+ ", +" d s s s V S V S %.{.{.5.3.3.d.d.q.q.q./+ o+[+!+c+9+|+9+c+9+c+9+c+9+9+|+9+m+ ", +" 0 s C s V V %.V {.^.{.5.5.3.3.D.d.q./+ n+{+[+{+[+c+c+|+9+9+9+|+9+c+9+|+|+G+ ", +" d w s M M M V %.%.{.3.{.3.d.d.d.q./+ w+[+[+{+&+{+{+{+9+c+9+c+9+c+|+9+c+B+ ", +" w s @.S S S %.%.{.5.5.^.3.b.D. G+@+[+[+[+c+[+<+[+9+c+|+c+9+9+c+|+m+ ", +" w s C M V V S %.^.{.{.3.5.N. C+@+[+{+&+{+&+<+[+{+{+{+9+9+9+c+9+c+G+ ", +" w M M S V {.V ^.5.5.{. w+,+,+@+[+[+{+[+{+c+9+<+[+9+9+9+9+{+D+ ", +" M @.V V {.{.#.++ w+@+@+@+[+{+[+[+{+[+&+[+[+{+c+{+{+{+x+ ", +" w.>.p t b ). 8+@+,+[+,+@+{+[+[+&+{+{+{+[+!+[+9+9+b+ ", +" +.b b n u %+ 2+#+,+@+Q.@+[+@+,+[+[+[+[+[+<+[+<+{+i+ ", +" b b k u u u+M.M.#+#+@+,+@+[+@+[+{+[+[+{+[+[+[+[+{+z+ ", +" b b n u u /. A+2+M.#+#+#+,+@+@+,+,+[+@+,+[+{+[+{+{+[+<+w+ ", +" t k k F u P /.7+ A+e+z.#+#+@+M.#+#+,+#+@+Q.[+@+@+,+{+&+[+{+[+B+ ", +" Y n u u E Q U U T.7+ f+4+I.M.>+M.M.Y.@+M.@+#+@+,+@+@+[+[+[+[+[+[+[+n+ ", +" k n F Q Q U .=._.8.G.(+(+)+g.i.z.r.I.M.I.>+I.#+#+#+#+#+#+,+,+Q.,+@+,+@+{+{+o+ ", +" k u u E U U U =.=._.2.g.i.i.i.A.r.z.z.I.M.Y.#+>+#+#+#+Q.@+@+@+@+,+[+@+[+,+s+ ", +" ).n E E P U =.=.=.8._._.g.g.i.i.A.A.z.I.z.M.Y.M.M.M.#+#+#+,+@+@+@+[+,+@+g+ ", +" u u Q U U U =._._.2.g.g.g.A.A.A.z.A.z.M.I.I.Y.#+#+#+#+@+#+,+,+,+,+@+o+ ", +" ).F Q U U =.=.=.8._.2.2.g.r.r.r.I.I.I.z.M.I.M.#+M.#+#+#+#+@+@+@+,+w+ ", +" Q Q P U U =._._.2._.g.g.g.i.A.A.A.A.I.I.M.X.M.#+@+#+@+@+@+,+#+z+ ", +" u.U /.U U 8._.8._.2.2.g.g.i.A.A.I.z.I.I.M.I.Y.>+@+#+#+#+#+#+A+ ", +" ].U U =.=.=.2.2._.g.i.i.A.i.A.A.I.z.I.>+Y.>+Y.Y.#+#+#+n+ ", +" /.U .=.=._._.2.2.g.i.A.A.z.A.I.I.M.I.M.M.M.M.Y.M.z+ ", +" /.=.8._._.2._.g.g.g.g.i.A.z.A.z.I.I.Y.I.X.#+8+ ", +" /.8.8._._.2.2.i.i.A.i.A.z.z.I.I.I.M.M.8+A+ ", +" }+8._.2.2.g.2.A.i.A.A.A.>+z.z.z.4+A+ ", +" T.)+_.g.2.A.r.A.A.r.A.4+z+ ", +" }+}+(+(+f+f+A+ ", +" ", +" "}; diff --git a/GraphicsView/include/CGAL/Qt/vec.h b/GraphicsView/include/CGAL/Qt/vec.h new file mode 100644 index 00000000000..0a6e2e2e95b --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/vec.h @@ -0,0 +1,368 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 + +#ifndef QGLVIEWER_VEC_H +#define QGLVIEWER_VEC_H + +#include +#include + +#include + +// Included by all files as vec.h is at the end of the include hierarchy +#include + +namespace CGAL{ +namespace qglviewer { + +/*! \brief The Vec class represents 3D positions and 3D vectors. + \class Vec vec.h CGAL::QGLViewer/vec.h + + Vec is used as a parameter and return type by many methods of the library. It + provides classical algebraic computational methods and is compatible with + OpenGL: + + \code + // Draws a point located at 3.0 OpenGL units in front of the camera + Vec pos = camera()->position() + 3.0 * camera()->viewDirection(); + glBegin(GL_POINTS); + glVertex3fv(pos); + glEnd(); + \endcode + + This makes of Vec a good candidate for representing positions and vectors in + your programs. Since it is part of the \c qglviewer namespace, specify \c + CGAL::qglviewer::Vec or use the qglviewer namespace: \code using namespace + qglviewer; \endcode + +

Interface with other vector classes

+ + Vec implements a universal explicit converter, based on the \c [] \c operator. + Everywhere a \c const \c Vec& argument is expected, you can use your own + vector type instead, as long as it implements this operator (see the Vec(const + C& c) documentation). + + See also the Quaternion and the Frame documentations. + \nosubgrouping */ +class CGAL_QT_EXPORT Vec { + +// If your compiler complains the "The class "CGAL::qglviewer::Vec" has no member +// "x"." Add your architecture Q_OS_XXXX flag (see qglobal.h) in this list. +#if defined(Q_OS_IRIX) || defined(Q_OS_AIX) || defined(Q_OS_HPUX) +#define QGLVIEWER_UNION_NOT_SUPPORTED +#endif + +public: +/*! The internal data representation is public. One can use v.x, v.y, v.z. See + * also operator[](). */ +#if defined(DOXYGEN) || defined(QGLVIEWER_UNION_NOT_SUPPORTED) + qreal x, y, z; +#else + union { + struct { + qreal x, y, z; + }; + qreal v_[3]; + }; +#endif + + /*! @name Setting the value */ + //@{ + /*! Default constructor. Value is set to (0,0,0). */ + Vec() : x(0.0), y(0.0), z(0.0) {} + + /*! Standard constructor with the x, y and z values. */ + Vec(qreal X, qreal Y, qreal Z) : x(X), y(Y), z(Z) {} + + /*! Universal explicit converter from any class to Vec. You can use your own +vector class everywhere a \c const \c Vec& parameter is required, as long as it +implements the \c operator[ ]: + +\code +class MyVec +{ + // ... + qreal operator[](int i) const { returns x, y or z when i=0, 1 or 2; } +} + +MyVec v(...); +camera()->setPosition(v); +\endcode + +Note that standard vector types (STL, \c qreal[3], ...) implement this operator +and can hence be used in place of Vec. See also operator const qreal*() .*/ + template explicit Vec(const C &c) : x(c[0]), y(c[1]), z(c[2]) {} + // Should NOT be explicit to prevent conflicts with operator<<. + + // ! Copy constructor + // Vec(const Vec& v) : x(v.x), y(v.y), z(v.z) {} + + /*! Equal operator. */ + Vec &operator=(const Vec &v) { + x = v.x; + y = v.y; + z = v.z; + return *this; + } + + /*! Set the current value. May be faster than using operator=() with a + * temporary Vec(x,y,z). */ + void setValue(qreal X, qreal Y, qreal Z) { + x = X; + y = Y; + z = Z; + } + + // Universal equal operator which allows the use of any type in place of Vec, + // as long as the [] operator is implemented (v[0]=v.x, v[1]=v.y, v[2]=v.z). + // template + // Vec& operator=(const C& c) + // { + // x=c[0]; y=c[1]; z=c[2]; + // return *this; + // } + //@} + + /*! @name Accessing the value */ + //@{ + /*! Bracket operator, with a constant return value. \p i must range in [0..2]. + */ + qreal operator[](int i) const { +#ifdef QGLVIEWER_UNION_NOT_SUPPORTED + return (&x)[i]; +#else + return v_[i]; +#endif + } + + /*! Bracket operator returning an l-value. \p i must range in [0..2]. */ + qreal &operator[](int i) { +#ifdef QGLVIEWER_UNION_NOT_SUPPORTED + return (&x)[i]; +#else + return v_[i]; +#endif + } + + /*! Conversion operator returning the memory address of the vector. + +Very convenient to pass a Vec pointer as a parameter to \c GLdouble OpenGL +functions: \code Vec pos, normal; glNormal3dv(normal); glVertex3dv(pos); +\endcode */ + operator const qreal *() const { +#ifdef QGLVIEWER_UNION_NOT_SUPPORTED + return &x; +#else + return v_; +#endif + } + + /*! Non const conversion operator returning the memory address of the vector. + +Useful to pass a Vec to a method that requires and fills a \c qreal*, as +provided by certain libraries. */ + operator qreal *() { +#ifdef QGLVIEWER_UNION_NOT_SUPPORTED + return &x; +#else + return v_; +#endif + } + + /*! Conversion operator returning the memory address of the vector. + +Very convenient to pass a Vec pointer as a \c float parameter to OpenGL +functions: \code Vec pos, normal; glNormal3fv(normal); glVertex3fv(pos); +\endcode +\note The returned float array is a static shared by all \c Vec instances. */ + operator const float *() const { + static float *const result = new float[3]; + result[0] = (float)x; + result[1] = (float)y; + result[2] = (float)z; + return result; + } + //@} + + /*! @name Algebraic computations */ + //@{ + /*! Returns the sum of the two vectors. */ + friend Vec operator+(const Vec &a, const Vec &b) { + return Vec(a.x + b.x, a.y + b.y, a.z + b.z); + } + + /*! Returns the difference of the two vectors. */ + friend Vec operator-(const Vec &a, const Vec &b) { + return Vec(a.x - b.x, a.y - b.y, a.z - b.z); + } + + /*! Unary minus operator. */ + friend Vec operator-(const Vec &a) { return Vec(-a.x, -a.y, -a.z); } + + /*! Returns the product of the vector with a scalar. */ + friend Vec operator*(const Vec &a, qreal k) { + return Vec(a.x * k, a.y * k, a.z * k); + } + + /*! Returns the product of a scalar with the vector. */ + friend Vec operator*(qreal k, const Vec &a) { return a * k; } + + /*! Returns the division of the vector with a scalar. + +Too small \p k values are \e not tested (unless the library was compiled with +the "debug" Qt \c CONFIG flag) and may result in \c NaN values. */ + friend Vec operator/(const Vec &a, qreal k) { +#ifndef QT_NO_DEBUG + if (fabs(k) < 1.0E-10) + qWarning("Vec::operator / : dividing by a null value (%f)", k); +#endif + return Vec(a.x / k, a.y / k, a.z / k); + } + + /*! Returns \c true only when the two vector are not equal (see operator==()). + */ + friend bool operator!=(const Vec &a, const Vec &b) { return !(a == b); } + + /*! Returns \c true when the squaredNorm() of the difference vector is lower + * than 1E-10. */ + friend bool operator==(const Vec &a, const Vec &b) { + const qreal epsilon = 1.0E-10; + return (a - b).squaredNorm() < epsilon; + } + + /*! Adds \p a to the vector. */ + Vec &operator+=(const Vec &a) { + x += a.x; + y += a.y; + z += a.z; + return *this; + } + + /*! Subtracts \p a to the vector. */ + Vec &operator-=(const Vec &a) { + x -= a.x; + y -= a.y; + z -= a.z; + return *this; + } + + /*! Multiply the vector by a scalar \p k. */ + Vec &operator*=(qreal k) { + x *= k; + y *= k; + z *= k; + return *this; + } + + /*! Divides the vector by a scalar \p k. + +An absolute \p k value lower than 1E-10 will print a warning if the library was +compiled with the "debug" Qt \c CONFIG flag. Otherwise, no test is performed for +efficiency reasons. */ + Vec &operator/=(qreal k) { +#ifndef QT_NO_DEBUG + if (fabs(k) < 1.0E-10) + qWarning("Vec::operator /= : dividing by a null value (%f)", k); +#endif + x /= k; + y /= k; + z /= k; + return *this; + } + + /*! Dot product of the two Vec. */ + friend qreal operator*(const Vec &a, const Vec &b) { + return a.x * b.x + a.y * b.y + a.z * b.z; + } + + /*! Cross product of the two vectors. Same as cross(). */ + friend Vec operator^(const Vec &a, const Vec &b) { return cross(a, b); } + + /*! Cross product of the two Vec. Mind the order ! */ + friend Vec cross(const Vec &a, const Vec &b) { + return Vec(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, + a.x * b.y - a.y * b.x); + } + + Vec orthogonalVec() const; +//@} + +/*! @name Norm of the vector */ +//@{ + + /*! Returns the \e squared norm of the Vec. */ + qreal squaredNorm() const { return x * x + y * y + z * z; } + + /*! Returns the norm of the vector. */ + qreal norm() const { return sqrt(x * x + y * y + z * z); } + + /*! Normalizes the Vec and returns its original norm. + +Normalizing a null vector will result in \c NaN values. */ + qreal normalize() { + const qreal n = norm(); +#ifndef QT_NO_DEBUG + if (n < 1.0E-10) + qWarning("Vec::normalize: normalizing a null vector (norm=%f)", n); +#endif + *this /= n; + return n; + } + + /*! Returns a unitary (normalized) \e representation of the vector. The + * original Vec is not modified. */ + Vec unit() const { + Vec v = *this; + v.normalize(); + return v; + } + //@} + + /*! @name Projection */ + //@{ + void projectOnAxis(const Vec &direction); + void projectOnPlane(const Vec &normal); + //@} + + /*! @name XML representation */ + //@{ + explicit Vec(const QDomElement &element); + QDomElement domElement(const QString &name, QDomDocument &document) const; + void initFromDOMElement(const QDomElement &element); +//@} + +#ifdef DOXYGEN + /*! @name Output stream */ + //@{ + /*! Output stream operator. Enables debugging code like: +\code +Vec pos(...); +cout << "Position=" << pos << endl; +\endcode */ + std::ostream &operator<<(std::ostream &o, const CGAL::qglviewer::Vec &); +//@} +#endif +}; + +}} // namespace CGAL::qglviewer + +std::ostream &operator<<(std::ostream &o, const CGAL::qglviewer::Vec &); + +#endif // QGLVIEWER_VEC_H diff --git a/GraphicsView/include/CGAL/Qt/vec_impl.h b/GraphicsView/include/CGAL/Qt/vec_impl.h new file mode 100644 index 00000000000..340c6cbf62c --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/vec_impl.h @@ -0,0 +1,181 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 + +#ifdef CGAL_HEADER_ONLY +#define CGAL_INLINE_FUNCTION inline + +#include + +#else +#define CGAL_INLINE_FUNCTION +#endif + +#include +#include + +// Most of the methods are declared inline in vec.h + +namespace CGAL{ +namespace qglviewer{ + + +/*! Projects the Vec on the axis of direction \p direction that passes through +the origin. + +\p direction does not need to be normalized (but must be non null). */ +CGAL_INLINE_FUNCTION +void Vec::projectOnAxis(const Vec &direction) { +#ifndef QT_NO_DEBUG + if (direction.squaredNorm() < 1.0E-10) + qWarning("Vec::projectOnAxis: axis direction is not normalized (norm=%f).", + direction.norm()); +#endif + + *this = (((*this) * direction) / direction.squaredNorm()) * direction; +} + +/*! Projects the Vec on the plane whose normal is \p normal that passes through +the origin. + +\p normal does not need to be normalized (but must be non null). */ +CGAL_INLINE_FUNCTION +void Vec::projectOnPlane(const Vec &normal) { +#ifndef QT_NO_DEBUG + if (normal.squaredNorm() < 1.0E-10) + qWarning("Vec::projectOnPlane: plane normal is not normalized (norm=%f).", + normal.norm()); +#endif + + *this -= (((*this) * normal) / normal.squaredNorm()) * normal; +} + +/*! Returns a Vec orthogonal to the Vec. Its norm() depends on the Vec, but is + zero only for a null Vec. Note that the function that associates an + orthogonalVec() to a Vec is not continous. */ +CGAL_INLINE_FUNCTION +Vec Vec::orthogonalVec() const { + // Find smallest component. Keep equal case for null values. + if ((fabs(y) >= 0.9 * fabs(x)) && (fabs(z) >= 0.9 * fabs(x))) + return Vec(0.0, -z, y); + else if ((fabs(x) >= 0.9 * fabs(y)) && (fabs(z) >= 0.9 * fabs(y))) + return Vec(-z, 0.0, x); + else + return Vec(-y, x, 0.0); +} + +/*! Constructs a Vec from a \c QDomElement representing an XML code of the form + \code< anyTagName x=".." y=".." z=".." />\endcode + +If one of these attributes is missing or is not a number, a warning is displayed +and the associated value is set to 0.0. + +See also domElement() and initFromDOMElement(). */ +CGAL_INLINE_FUNCTION +Vec::Vec(const QDomElement &element) { + QStringList attribute; + attribute << "x" + << "y" + << "z"; + for (int i = 0; i < attribute.size(); ++i) +#ifdef QGLVIEWER_UNION_NOT_SUPPORTED + this->operator[](i) = DomUtils::qrealFromDom(element, attribute[i], 0.0); +#else + v_[i] = DomUtils::qrealFromDom(element, attribute[i], 0.0); +#endif +} + +/*! Returns an XML \c QDomElement that represents the Vec. + + \p name is the name of the QDomElement tag. \p doc is the \c QDomDocument + factory used to create QDomElement. + + When output to a file, the resulting QDomElement will look like: + \code + + \endcode + + Use initFromDOMElement() to restore the Vec state from the resulting \c + QDomElement. See also the Vec(const QDomElement&) constructor. + + Here is complete example that creates a QDomDocument and saves it into a file: + \code + Vec sunPos; + QDomDocument document("myDocument"); + QDomElement sunElement = document.createElement("Sun"); + document.appendChild(sunElement); + sunElement.setAttribute("brightness", sunBrightness()); + sunElement.appendChild(sunPos.domElement("sunPosition", document)); + // Other additions to the document hierarchy... + + // Save doc document + QFile f("myFile.xml"); + if (f.open(IO_WriteOnly)) + { + QTextStream out(&f); + document.save(out, 2); + f.close(); + } + \endcode + +CGAL_INLINE_FUNCTION + See also Quaternion::domElement(), Frame::domElement(), Camera::domElement()... + */ +CGAL_INLINE_FUNCTION +QDomElement Vec::domElement(const QString &name, QDomDocument &document) const { + QDomElement de = document.createElement(name); + de.setAttribute("x", QString::number(x)); + de.setAttribute("y", QString::number(y)); + de.setAttribute("z", QString::number(z)); + return de; +} + +/*! Restores the Vec state from a \c QDomElement created by domElement(). + + The \c QDomElement should contain \c x, \c y and \c z attributes. If one of + these attributes is missing or is not a number, a warning is displayed and the + associated value is set to 0.0. + + To restore the Vec state from an xml file, use: + \code + // Load DOM from file + QDomDocument doc; + QFile f("myFile.xml"); + if (f.open(IO_ReadOnly)) + { + doc.setContent(&f); + f.close(); + } + // Parse the DOM tree and initialize + QDomElement main=doc.documentElement(); + myVec.initFromDOMElement(main); + \endcode + + See also the Vec(const QDomElement&) constructor. */ +CGAL_INLINE_FUNCTION +void Vec::initFromDOMElement(const QDomElement &element) { + const Vec v(element); + *this = v; +} + +CGAL_INLINE_FUNCTION +std::ostream &operator<<(std::ostream &o, const Vec &v) { + return o << v.x << '\t' << v.y << '\t' << v.z; +} +}} diff --git a/GraphicsView/include/CGAL/Qt/viewer_actions.h b/GraphicsView/include/CGAL/Qt/viewer_actions.h new file mode 100644 index 00000000000..e07f2227796 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/viewer_actions.h @@ -0,0 +1,101 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork of the QGLViewer library version 2.7.0. + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0 +#ifndef VIEWER_ACTIONS_H +#define VIEWER_ACTIONS_H +namespace CGAL{ +namespace qglviewer { +/*! Defines the different actions that can be associated with a keyboard +shortcut using setShortcut(). + +See the keyboard page for details. */ +enum KeyboardAction { + DRAW_AXIS, + DRAW_GRID, + DISPLAY_FPS, + ENABLE_TEXT, + EXIT_VIEWER, + CAMERA_MODE, + FULL_SCREEN, + STEREO, + ANIMATION, + HELP, + EDIT_CAMERA, + MOVE_CAMERA_LEFT, + MOVE_CAMERA_RIGHT, + MOVE_CAMERA_UP, + MOVE_CAMERA_DOWN, + INCREASE_FLYSPEED, + DECREASE_FLYSPEED +}; + +/*! Defines the different mouse handlers: camera() or manipulatedFrame(). + +Used by setMouseBinding(), setMouseBinding(Qt::KeyboardModifiers modifiers, +Qt::MouseButtons, ClickAction, bool, int) and setWheelBinding() to define +which handler receives the mouse events. */ +enum MouseHandler { CAMERA, FRAME }; + +/*! Defines the possible actions that can be binded to a mouse click using +setMouseBinding(Qt::KeyboardModifiers, Qt::MouseButtons, ClickAction, bool, +int). + +See the mouse page for details. */ +enum ClickAction { + NO_CLICK_ACTION, + ZOOM_ON_PIXEL, + ZOOM_TO_FIT, + SELECT, + RAP_FROM_PIXEL, + RAP_IS_CENTER, + CENTER_FRAME, + CENTER_SCENE, + SHOW_ENTIRE_SCENE, + ALIGN_FRAME, + ALIGN_CAMERA +}; + +/*! Defines the possible actions that can be binded to a mouse action (a +click, followed by a mouse displacement). + +These actions may be binded to the camera() or to the manipulatedFrame() (see +CGAL::QGLViewer::MouseHandler) using setMouseBinding(). */ +enum MouseAction { + NO_MOUSE_ACTION, + ROTATE, + ZOOM, + TRANSLATE, + MOVE_FORWARD, + LOOK_AROUND, + MOVE_BACKWARD, + SCREEN_ROTATE, + ROLL, + DRIVE, + SCREEN_TRANSLATE, + ZOOM_ON_REGION +}; + +enum SnapShotBackground { + CURRENT_BACKGROUND=0, + TRANSPARENT_BACKGROUND, + CHOOSE_BACKGROUND +}; + +}} +#endif // VIEWER_ACTIONS_H diff --git a/GraphicsView/package_info/GraphicsView/license.txt b/GraphicsView/package_info/GraphicsView/license.txt index 8bb8efcb72b..3ca1763d670 100644 --- a/GraphicsView/package_info/GraphicsView/license.txt +++ b/GraphicsView/package_info/GraphicsView/license.txt @@ -1 +1,3 @@ GPL (v3 or later) +LGPL (v3 or later) +UNKNOWN diff --git a/GraphicsView/src/CGAL_Qt5/CMakeLists.txt b/GraphicsView/src/CGAL_Qt5/CMakeLists.txt index 173fb87e2e9..224de8bbe4b 100644 --- a/GraphicsView/src/CGAL_Qt5/CMakeLists.txt +++ b/GraphicsView/src/CGAL_Qt5/CMakeLists.txt @@ -13,9 +13,9 @@ if(CGAL_Qt5_MISSING_DEPS) endif() message( STATUS "USING Qt5_VERSION = '${Qt5Core_VERSION_STRING}'" ) - if(NOT CGAL_HEADER_ONLY) - collect_cgal_library( CGAL_Qt5 "${_CGAL_Qt5_MOC_FILES_private};${_CGAL_Qt5_RESOURCE_FILES_private}") + collect_cgal_library( CGAL_Qt5 "${_CGAL_Qt5_MOC_FILES_private};${_CGAL_Qt5_RESOURCE_FILES_private};${_CGAL_Qt5_UI_FILES}") + target_include_directories( CGAL_Qt5 PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) else() collect_cgal_library( CGAL_Qt5 "") endif() diff --git a/GraphicsView/src/CGAL_Qt5/camera.cpp b/GraphicsView/src/CGAL_Qt5/camera.cpp new file mode 100644 index 00000000000..cbc707c5055 --- /dev/null +++ b/GraphicsView/src/CGAL_Qt5/camera.cpp @@ -0,0 +1,27 @@ +/**************************************************************************** + + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of the CGAL::QGLViewer library version 2.7.0. + + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + versions 2.0 or 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + In addition, as a special exception, Gilles Debunne gives you certain + additional rights, described in the file GPL_EXCEPTION in this package. + + libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must + purchase a libCGAL::QGLViewer Commercial License. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +#ifndef CGAL_HEADER_ONLY + +#include +#include + +#endif // CGAL_HEADER_ONLY diff --git a/GraphicsView/src/CGAL_Qt5/constraint.cpp b/GraphicsView/src/CGAL_Qt5/constraint.cpp new file mode 100644 index 00000000000..b1f9038937b --- /dev/null +++ b/GraphicsView/src/CGAL_Qt5/constraint.cpp @@ -0,0 +1,27 @@ +/**************************************************************************** + + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of the CGAL::QGLViewer library version 2.7.0. + + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + versions 2.0 or 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + In addition, as a special exception, Gilles Debunne gives you certain + additional rights, described in the file GPL_EXCEPTION in this package. + + libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must + purchase a libCGAL::QGLViewer Commercial License. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +#ifndef CGAL_HEADER_ONLY + +#include +#include + +#endif // CGAL_HEADER_ONLY diff --git a/GraphicsView/src/CGAL_Qt5/frame.cpp b/GraphicsView/src/CGAL_Qt5/frame.cpp new file mode 100644 index 00000000000..56fdd80b851 --- /dev/null +++ b/GraphicsView/src/CGAL_Qt5/frame.cpp @@ -0,0 +1,27 @@ +/**************************************************************************** + + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of the CGAL::QGLViewer library version 2.7.0. + + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + versions 2.0 or 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + In addition, as a special exception, Gilles Debunne gives you certain + additional rights, described in the file GPL_EXCEPTION in this package. + + libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must + purchase a libCGAL::QGLViewer Commercial License. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +#ifndef CGAL_HEADER_ONLY + +#include +#include + +#endif // CGAL_HEADER_ONLY diff --git a/GraphicsView/src/CGAL_Qt5/keyFrameInterpolator.cpp b/GraphicsView/src/CGAL_Qt5/keyFrameInterpolator.cpp new file mode 100644 index 00000000000..002dc1a7b29 --- /dev/null +++ b/GraphicsView/src/CGAL_Qt5/keyFrameInterpolator.cpp @@ -0,0 +1,27 @@ +/**************************************************************************** + + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of the CGAL::QGLViewer library version 2.7.0. + + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + versions 2.0 or 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + In addition, as a special exception, Gilles Debunne gives you certain + additional rights, described in the file GPL_EXCEPTION in this package. + + libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must + purchase a libCGAL::QGLViewer Commercial License. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +#ifndef CGAL_HEADER_ONLY + +#include +#include + +#endif // CGAL_HEADER_ONLY diff --git a/GraphicsView/src/CGAL_Qt5/manipulatedCameraFrame.cpp b/GraphicsView/src/CGAL_Qt5/manipulatedCameraFrame.cpp new file mode 100644 index 00000000000..10ef6e64ee1 --- /dev/null +++ b/GraphicsView/src/CGAL_Qt5/manipulatedCameraFrame.cpp @@ -0,0 +1,27 @@ +/**************************************************************************** + + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of the CGAL::QGLViewer library version 2.7.0. + + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + versions 2.0 or 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + In addition, as a special exception, Gilles Debunne gives you certain + additional rights, described in the file GPL_EXCEPTION in this package. + + libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must + purchase a libCGAL::QGLViewer Commercial License. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +#ifndef CGAL_HEADER_ONLY + +#include +#include + +#endif // CGAL_HEADER_ONLY diff --git a/GraphicsView/src/CGAL_Qt5/manipulatedFrame.cpp b/GraphicsView/src/CGAL_Qt5/manipulatedFrame.cpp new file mode 100644 index 00000000000..29a61c0a42e --- /dev/null +++ b/GraphicsView/src/CGAL_Qt5/manipulatedFrame.cpp @@ -0,0 +1,27 @@ +/**************************************************************************** + + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of the CGAL::QGLViewer library version 2.7.0. + + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + versions 2.0 or 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + In addition, as a special exception, Gilles Debunne gives you certain + additional rights, described in the file GPL_EXCEPTION in this package. + + libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must + purchase a libCGAL::QGLViewer Commercial License. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +#ifndef CGAL_HEADER_ONLY + +#include +#include + +#endif // CGAL_HEADER_ONLY diff --git a/GraphicsView/src/CGAL_Qt5/mouseGrabber.cpp b/GraphicsView/src/CGAL_Qt5/mouseGrabber.cpp new file mode 100644 index 00000000000..5430d8f89f7 --- /dev/null +++ b/GraphicsView/src/CGAL_Qt5/mouseGrabber.cpp @@ -0,0 +1,27 @@ +/**************************************************************************** + + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of the CGAL::QGLViewer library version 2.7.0. + + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + versions 2.0 or 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + In addition, as a special exception, Gilles Debunne gives you certain + additional rights, described in the file GPL_EXCEPTION in this package. + + libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must + purchase a libCGAL::QGLViewer Commercial License. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +#ifndef CGAL_HEADER_ONLY + +#include +#include + +#endif // CGAL_HEADER_ONLY diff --git a/GraphicsView/src/CGAL_Qt5/qglviewer.cpp b/GraphicsView/src/CGAL_Qt5/qglviewer.cpp new file mode 100644 index 00000000000..1c81fbc80a2 --- /dev/null +++ b/GraphicsView/src/CGAL_Qt5/qglviewer.cpp @@ -0,0 +1,27 @@ +/**************************************************************************** + + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of the CGAL::QGLViewer library version 2.7.0. + + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + versions 2.0 or 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + In addition, as a special exception, Gilles Debunne gives you certain + additional rights, described in the file GPL_EXCEPTION in this package. + + libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must + purchase a libCGAL::QGLViewer Commercial License. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +#ifndef CGAL_HEADER_ONLY + +#include +#include + +#endif // CGAL_HEADER_ONLY diff --git a/GraphicsView/src/CGAL_Qt5/quaternion.cpp b/GraphicsView/src/CGAL_Qt5/quaternion.cpp new file mode 100644 index 00000000000..24a9ab32690 --- /dev/null +++ b/GraphicsView/src/CGAL_Qt5/quaternion.cpp @@ -0,0 +1,27 @@ +/**************************************************************************** + + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of the CGAL::QGLViewer library version 2.7.0. + + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + versions 2.0 or 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + In addition, as a special exception, Gilles Debunne gives you certain + additional rights, described in the file GPL_EXCEPTION in this package. + + libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must + purchase a libCGAL::QGLViewer Commercial License. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +#ifndef CGAL_HEADER_ONLY + +#include +#include + +#endif // CGAL_HEADER_ONLY diff --git a/GraphicsView/src/CGAL_Qt5/vec.cpp b/GraphicsView/src/CGAL_Qt5/vec.cpp new file mode 100644 index 00000000000..5a0df102a41 --- /dev/null +++ b/GraphicsView/src/CGAL_Qt5/vec.cpp @@ -0,0 +1,27 @@ +/**************************************************************************** + + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of the CGAL::QGLViewer library version 2.7.0. + + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + versions 2.0 or 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + In addition, as a special exception, Gilles Debunne gives you certain + additional rights, described in the file GPL_EXCEPTION in this package. + + libCGAL::QGLViewer uses dual licensing. Commercial/proprietary software must + purchase a libCGAL::QGLViewer Commercial License. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ +#ifndef CGAL_HEADER_ONLY + +#include +#include + +#endif // CGAL_HEADER_ONLY diff --git a/HalfedgeDS/include/CGAL/HalfedgeDS_const_decorator.h b/HalfedgeDS/include/CGAL/HalfedgeDS_const_decorator.h index 62bd7971d1e..fe84a6c79aa 100644 --- a/HalfedgeDS/include/CGAL/HalfedgeDS_const_decorator.h +++ b/HalfedgeDS/include/CGAL/HalfedgeDS_const_decorator.h @@ -261,7 +261,7 @@ is_valid( bool verb, int level) const { if ( begin->is_border()) ++nb; } - verr << "summe border halfedges (2*nb) = " << 2 * nb << std::endl; + verr << "sum border halfedges (2*nb) = " << 2 * nb << std::endl; if ( valid && n != hds->size_of_halfedges()) verr << "counting halfedges failed." << std::endl; if ( valid && level >= 4 && (nb != hds->size_of_border_halfedges())) diff --git a/Hash_map/test/Hash_map/Hash.cpp b/Hash_map/test/Hash_map/Hash.cpp index fd558a42659..77e2c5c3b2f 100644 --- a/Hash_map/test/Hash_map/Hash.cpp +++ b/Hash_map/test/Hash_map/Hash.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include diff --git a/Homogeneous_kernel/include/CGAL/Homogeneous/function_objects.h b/Homogeneous_kernel/include/CGAL/Homogeneous/function_objects.h index 080bd4929ea..40c2e3b2f65 100644 --- a/Homogeneous_kernel/include/CGAL/Homogeneous/function_objects.h +++ b/Homogeneous_kernel/include/CGAL/Homogeneous/function_objects.h @@ -3315,6 +3315,7 @@ namespace HomogeneousKernelFunctors { typedef typename K::Vector_3 Vector_3; typedef typename K::Triangle_3 Triangle_3; typedef typename K::Segment_3 Segment_3; + typedef typename K::Ray_3 Ray_3; public: typedef Point_3 result_type; @@ -3351,6 +3352,10 @@ namespace HomogeneousKernelFunctors { Point_3 operator()( const Segment_3& s, const Point_3& p ) const { return CommonKernelFunctors::Construct_projected_point_3()(p,s,K()); } + + Point_3 + operator()( const Ray_3& r, const Point_3& p ) const + { return CommonKernelFunctors::Construct_projected_point_3()(p,r,K()); } }; template diff --git a/Inscribed_areas/include/CGAL/extremal_polygon_2.h b/Inscribed_areas/include/CGAL/extremal_polygon_2.h index de741b5d44c..d50d1ddd4f0 100644 --- a/Inscribed_areas/include/CGAL/extremal_polygon_2.h +++ b/Inscribed_areas/include/CGAL/extremal_polygon_2.h @@ -41,7 +41,7 @@ namespace CGAL { //!!! This will eventually be integrated into function_objects.h template < class Array, class Index, class Element > struct Index_operator -: public CGAL::binary_function< Array, Index, Element > +: public CGAL::cpp98::binary_function< Array, Index, Element > { Element& operator()( Array& a, const Index& i) const diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index 1e32c9b7790..06af473b88a 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -26,6 +26,27 @@ Release 4.13 Release date: September 2018 +### Installation + +- The library CGAL_Qt5 now contains a fork of the version 2.7.0 of libQGLViewer. + The corresponding code is in the package GraphicsView. + The dependency for the external library libQGLViewer is therefore dropped for all demos. + +### General + + - A new function `CGAL::draw()` is added in the packages Polyhedral + Surface, Surface Mesh, Linear Cell Complex, 2D Triangulations, and 3D + Triangulations, enabling to draw the corresponding data structures. + +### 2D and 3D Linear Geometry Kernel +- An operator() that takes a Ray_3 has been added to the concept + ConstructProjectedPoint 3. + + +### CGAL and Boost Property Maps + +- Addition of a read-write property map to convert on-the-fly geometric + object from Cartesian kernels ### 2D Triangulations @@ -48,6 +69,46 @@ Release date: September 2018 to reflect the real needs of the code (some types and operators were used in the code but did not appear in the concepts). +### Polygon Mesh Processing +- Added a function to apply a transformation to a mesh: + - `CGAL::Polygon_mesh_processing::transform()` + +- Fix a bug in `isotropic_remeshing()` making constrained vertices missing in the output +- Guarantee that constrained vertices are kept in the mesh after calling `isotropic_remeshing()` + (and not only the points associated to constrained vertices as it was before). + +### 3D Mesh Generation + +- **Breaking change:** The template parameters of the class template + `Labeled_mesh_domain_3` have been simplified. The three constructors of + that class template have been replaced by a new unique constructor + using Boost named parameters. Three new static template member + functions that act as named constructors have been added: + - `create_gray_image_mesh_domain()`, to create a domain from a 3D + gray image, + - `create_labeled_image_mesh_domain()`, to create a domain from a 3D + labeled image, and + - `create_implicit_mesh_domain()`, to create a domain from an + implicit function. + +- The class templates `Implicit_mesh_domain_3`, + `Gray_image_mesh_domain_3`, and `Labeled_image_mesh_domain_3` are now + deprecated. + +- **Breaking change:** The headers + `` and + ``, that were deprecated since + CGAL 4.5, are now removed. + +### CGAL and the Boost Graph Library (BGL) + +- Add helper function `CGAL::is_valid_polygon_mesh` that checks the + validity of a polygon mesh using BGL functions. + +- Improve the function `CGAL::Euler::collapse_edge` so that the target + vertex of the collapsed edge is always kept after the collapse. + + Release 4.12 ------------ @@ -222,7 +283,7 @@ Release date: April 2018 ### CGAL and the Boost Graph Library (BGL) -- Added helper function `CGAL::expand_face_selection_for_removal` that +- Add helper function `CGAL::expand_face_selection_for_removal` that expands a face selection to avoid creating a non manifold mesh when removing the selected faces. diff --git a/Installation/CMakeLists.txt b/Installation/CMakeLists.txt index d5173fdf76b..4a45bf89485 100644 --- a/Installation/CMakeLists.txt +++ b/Installation/CMakeLists.txt @@ -562,7 +562,7 @@ message("== Detect external libraries ==") # External libs configured when Qt5 lib of cgal are required # Coin is used in KDS, but no FindCoin or FindCOIN exists # There exists FindF2C, FindIPE, FindMKL, but they are only used to support supporting libs -list (INSERT CGAL_SUPPORTING_3RD_PARTY_LIBRARIES 0 GMP MPFR ZLIB OpenGL LEDA MPFI RS RS3 OpenNL Eigen3 BLAS LAPACK QGLViewer ESBTL Coin3D NTL IPE) +list (INSERT CGAL_SUPPORTING_3RD_PARTY_LIBRARIES 0 GMP MPFR ZLIB OpenGL LEDA MPFI RS RS3 OpenNL Eigen3 BLAS LAPACK ESBTL Coin3D NTL IPE) if (NOT WIN32) # GMPXX is not supported on WIN32 machines list (INSERT CGAL_SUPPORTING_3RD_PARTY_LIBRARIES 1 GMPXX) @@ -580,7 +580,6 @@ endmacro() set_special_prefix(Qt5 QT) set_special_prefix(Eigen3 EIGEN3) -set_special_prefix(QGLViewer QGLVIEWER) set_special_prefix(Coin3D COIN3D) # some libraries are essential (stl and Boost.Thread are treated in another way) @@ -864,10 +863,8 @@ endif() if(NOT CGAL_HEADER_ONLY) create_CGALconfig_files() else() - if(NOT EXISTS "${CMAKE_BINARY_DIR}/CGALConfig.cmake") - configure_file("${CGAL_MODULES_DIR}/CGALConfig_binary_header_only.cmake.in" - "${CMAKE_BINARY_DIR}/CGALConfig.cmake" @ONLY) - endif() + configure_file("${CGAL_MODULES_DIR}/CGALConfig_binary_header_only.cmake.in" + "${CMAKE_BINARY_DIR}/CGALConfig.cmake" @ONLY) endif() #-------------------------------------------------------------------------------------------------- @@ -890,7 +887,9 @@ foreach (dir ${CGAL_CONFIGURED_PACKAGES}) install(DIRECTORY ${dir}/include/CGAL DESTINATION ${CGAL_INSTALL_INC_DIR} PATTERN ".svn" EXCLUDE) endif() endforeach() -install(DIRECTORY ${CMAKE_BINARY_DIR}/include/CGAL DESTINATION ${CGAL_INSTALL_INC_DIR} PATTERN ".svn" EXCLUDE) +if(EXISTS ${CMAKE_BINARY_DIR}/include/CGAL) + install(DIRECTORY ${CMAKE_BINARY_DIR}/include/CGAL DESTINATION ${CGAL_INSTALL_INC_DIR} PATTERN ".svn" EXCLUDE) +endif() file(GLOB scripts "scripts/*") list(SORT scripts) @@ -1058,8 +1057,7 @@ if ( CGAL_BRANCH_BUILD ) find_package(GMP REQUIRED) find_package(Doxygen REQUIRED) find_package(Eigen3 REQUIRED) - find_package(Qt5 COMPONENTS Core Widgets Xml OpenGL REQUIRED) - find_package(QGLViewer) + find_package(Qt5 COMPONENTS Core Widgets Xml OpenGL Gui REQUIRED) find_package(VTK COMPONENTS vtkImagingGeneral vtkIOImage NO_MODULE) find_package(IPE) find_package(RS3) @@ -1069,7 +1067,7 @@ if ( CGAL_BRANCH_BUILD ) set(compile_options "\ ${CMAKE_CXX_FLAGS} -DCGAL_EIGEN3_ENABLED -DCGAL_PROFILE \ -${Qt5Widgets_DEFINITIONS} ${Qt5Xml_DEFINITIONS} ${Qt5OpenGL_DEFINITIONS} \ +${Qt5Widgets_DEFINITIONS} ${Qt5Xml_DEFINITIONS} ${Qt5OpenGL_DEFINITIONS} ${Qt5Gui_DEFINITIONS} \ ${Qt5OpenGL_EXECUTABLE_COMPILE_FLAGS} -fPIC \ ${Qt5Gui_EXECUTABLE_COMPILE_FLAGS} \ ${Qt5Xml_EXECUTABLE_COMPILE_FLAGS} \ @@ -1122,13 +1120,13 @@ because IPE_FOUND is false.") endif() if(CGAL_ENABLE_CHECK_HEADERS) - set(falg "-fsyntax-only") + set(flag "-fsyntax-only") else() - set(falg "-E") + set(flag "-E") endif() if(NOT DEFINED CGAL_CHECK_SYNTAX_ONLY) execute_process(COMMAND - ${CMAKE_CXX_COMPILER} -x c++ ${falg} ${CGAL_MODULES_DIR}/config/support/test_syntaxonly.cpp + ${CMAKE_CXX_COMPILER} -x c++ ${flag} ${CGAL_MODULES_DIR}/config/support/test_syntaxonly.cpp ERROR_QUIET RESULT_VARIABLE ok) if(ok EQUAL 0) @@ -1139,7 +1137,7 @@ because IPE_FOUND is false.") endif(NOT DEFINED CGAL_CHECK_SYNTAX_ONLY) if(NOT CGAL_CHECK_SYNTAX_ONLY) - message(FATAL_ERROR "Your compiler does not seem to support ${falg}. + message(FATAL_ERROR "Your compiler does not seem to support ${flag}. You must disable CGAL_ENABLE_CHECK_HEADERS.") endif() @@ -1156,8 +1154,8 @@ You must disable CGAL_ENABLE_CHECK_HEADERS.") ${RS_INCLUDE_DIR} ${EIGEN3_INCLUDE_DIR} ${GMP_INCLUDE_DIR} - ${QGLVIEWER_INCLUDE_DIR} ${Qt5OpenGL_INCLUDE_DIRS} - ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Xml_INCLUDE_DIRS} + ${Qt5OpenGL_INCLUDE_DIRS} + ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Xml_INCLUDE_DIRS} ${Qt5Gui_DEFINITIONS} ${CGAL_3RD_PARTY_INCLUDE_DIRS} ${CGAL_Qt5_3RD_PARTY_INCLUDE_DIRS} ) list(APPEND include_options "-I${incdir}") @@ -1240,14 +1238,6 @@ You must disable CGAL_ENABLE_CHECK_HEADERS.") set(skip_hdr TRUE) endif() endif() - if(NOT QGLVIEWER_FOUND) - string(REGEX MATCH "CGAL/Three/.*" is_a_three_header ${header}) - if(is_a_three_header) - message(STATUS "Skip Three header \"${header}\" because \ -QGLVIEWER_FOUND is false.") - set(skip_hdr TRUE) - endif() - endif() if(NOT VTK_FOUND) string(REGEX MATCH ".*vtk.*" is_a_vtk_header ${header}) if(is_a_vtk_header) @@ -1270,6 +1260,7 @@ LEDA_FOUND is false.") endif() endif() if(NOT skip_hdr) + LIST( APPEND list_of_headers_to_test ${header}) string(REPLACE "/" "__" header2 "${header}") string(REPLACE "." "_" header2 "${header2}") string(REPLACE ";" " " include_options_str "${include_options}") @@ -1277,7 +1268,16 @@ LEDA_FOUND is false.") separate_arguments(CMD UNIX_COMMAND "${CMAKE_CXX_COMPILER} ${compile_options_str} -${include_options_str} -x c++ ${falg} -H \ +${include_options_str} -x c++ ${flag} -H \ +${CMAKE_CURRENT_SOURCE_DIR}/../${package}/include/${header}" + # The header Algebraic_kernel_rs_gmpz_d_1.h is skipped on purpose: it + # depends on RS. + ) + # CMD2 is CMD without the -H option + separate_arguments(CMD2 + UNIX_COMMAND + "${CMAKE_CXX_COMPILER} ${compile_options_str} +${include_options_str} -x c++ ${flag} \ ${CMAKE_CURRENT_SOURCE_DIR}/../${package}/include/${header}" # The header Algebraic_kernel_rs_gmpz_d_1.h is skipped on purpose: it # depends on RS. @@ -1288,6 +1288,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/../${package}/include/${header}" COMMAND ${CMAKE_COMMAND} -DCERR:STRING=${chk_header_name} "-DCMD:STRING=${CMD}" + "-DCMD2:STRING=${CMD2}" -P "${CGAL_MODULES_DIR}/run_cmd_redirection_cerr.cmake" DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../${package}/include/${header} DEPENDS ${CGAL_MODULES_DIR}/run_cmd_redirection_cerr.cmake @@ -1324,7 +1325,26 @@ ${CMAKE_CURRENT_SOURCE_DIR}/../${package}/include/${header}" list(REMOVE_DUPLICATES packages_deps) endif() endforeach() # loop on packages - add_custom_target(check_headers DEPENDS ${check_pkg_target_list}) + + #Now check that a cpp file including all documented headers compiles + file(WRITE ${CGAL_BINARY_DIR}/test_headers.cpp "#define BOOST_PARAMETER_MAX_ARITY 12 \n") + foreach(header ${list_of_headers_to_test}) + file(APPEND ${CGAL_BINARY_DIR}/test_headers.cpp "#include <${header}>\n") + endforeach() #loop on headers to include in test file + file(APPEND ${CGAL_BINARY_DIR}/test_headers.cpp "int main(){}\n") + + add_custom_target(check_headers + DEPENDS ${check_pkg_target_list}) + + string(REPLACE " " ";" compile_options ${compile_options}) + string(REPLACE " " ";" include_options ${include_options_str}) + add_custom_command(TARGET check_headers + POST_BUILD + COMMAND ${CMAKE_CXX_COMPILER} + ${compile_options} ${include_options} + -x c++ -fsyntax-only ${CGAL_BINARY_DIR}/test_headers.cpp + ) + add_custom_target(packages_dependencies DEPENDS ${packages_deps}) message( " \n\ You can now check the headers with the target `check_headers`\n\ diff --git a/Installation/INSTALL.md b/Installation/INSTALL.md index 043e7643757..17abb7c05ab 100644 --- a/Installation/INSTALL.md +++ b/Installation/INSTALL.md @@ -63,9 +63,6 @@ CGAL packages, some are only needed for demos. - Qt5 (>= 5.3) http://qt-project.org/ - - libQGLViewer - http://www.libqglviewer.com/ - - Geomview http://www.geomview.org/ Not supported with Visual C++ diff --git a/Installation/cmake/modules/CGAL_Qt5_moc_and_resource_files.cmake b/Installation/cmake/modules/CGAL_Qt5_moc_and_resource_files.cmake index 8be8a352486..63609720936 100644 --- a/Installation/cmake/modules/CGAL_Qt5_moc_and_resource_files.cmake +++ b/Installation/cmake/modules/CGAL_Qt5_moc_and_resource_files.cmake @@ -3,11 +3,21 @@ if(CGAL_Qt5_moc_and_resource_files_included) endif() set(CGAL_Qt5_moc_and_resource_files_included TRUE) -qt5_wrap_cpp(_CGAL_Qt5_MOC_FILES_private - ${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/GraphicsItem.h - ${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/GraphicsViewInput.h) +if(NOT CGAL_HEADER_ONLY) + qt5_wrap_cpp(_CGAL_Qt5_MOC_FILES_private + ${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/GraphicsItem.h + ${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/GraphicsViewInput.h + ${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/camera.h + ${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/frame.h + ${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/keyFrameInterpolator.h + ${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/manipulatedCameraFrame.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/image_interface.h + ) +endif()#CGAL_HEADER_ONLY # qrc files (resources files, that contain icons, at least) if(EXISTS ${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/demo/resources/CGAL.qrc) @@ -24,3 +34,5 @@ else() ${CGAL_MODULES_DIR}/demo/icons/File.qrc ${CGAL_MODULES_DIR}/demo/icons/Triangulation_2.qrc) endif() + +qt5_wrap_ui(_CGAL_Qt5_UI_FILES ${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/resources/ImageInterface.ui) diff --git a/Installation/cmake/modules/CGAL_SetupCGAL_Qt5Dependencies.cmake b/Installation/cmake/modules/CGAL_SetupCGAL_Qt5Dependencies.cmake index 9f75d1a61d4..2ab430f9200 100644 --- a/Installation/cmake/modules/CGAL_SetupCGAL_Qt5Dependencies.cmake +++ b/Installation/cmake/modules/CGAL_SetupCGAL_Qt5Dependencies.cmake @@ -24,7 +24,7 @@ set(CGAL_SetupCGAL_Qt5Dependencies_included TRUE) # Used Modules # ^^^^^^^^^^^^ # - :module:`Qt5Config` -find_package(Qt5 QUIET COMPONENTS OpenGL Svg) +find_package(Qt5 QUIET COMPONENTS OpenGL Svg Xml) set(CGAL_Qt5_MISSING_DEPS "") if(NOT Qt5OpenGL_FOUND) @@ -53,11 +53,27 @@ if(NOT CGAL_Qt5_MISSING_DEPS) include(${CMAKE_CURRENT_LIST_DIR}/CGAL_Qt5_moc_and_resource_files.cmake) if(CGAL_HEADER_ONLY AND (WITH_demos OR WITH_examples OR NOT CGAL_BUILDING_LIBS) AND NOT TARGET CGAL_Qt5_moc_and_resources) - add_library(CGAL_Qt5_moc_and_resources STATIC ${_CGAL_Qt5_MOC_FILES_private} ${_CGAL_Qt5_RESOURCE_FILES_private}) + add_library(CGAL_Qt5_moc_and_resources STATIC + ${_CGAL_Qt5_MOC_FILES_private} + ${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/GraphicsItem.h + ${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/GraphicsViewInput.h + ${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/camera.h + ${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/frame.h + ${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/keyFrameInterpolator.h + ${CGAL_GRAPHICSVIEW_PACKAGE_DIR}/include/CGAL/Qt/manipulatedCameraFrame.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/image_interface.h + ${_CGAL_Qt5_UI_FILES} + ${_CGAL_Qt5_RESOURCE_FILES_private}) + target_include_directories( CGAL_Qt5_moc_and_resources PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) set_target_properties(CGAL_Qt5_moc_and_resources PROPERTIES POSITION_INDEPENDENT_CODE TRUE - EXCLUDE_FROM_ALL TRUE) - target_link_libraries(CGAL_Qt5_moc_and_resources CGAL::CGAL Qt5::Widgets Qt5::OpenGL Qt5::Svg) + EXCLUDE_FROM_ALL TRUE + AUTOMOC TRUE) + target_link_libraries(CGAL_Qt5_moc_and_resources CGAL::CGAL Qt5::Widgets Qt5::OpenGL Qt5::Svg Qt5::Xml) add_library(CGAL::CGAL_Qt5_moc_and_resources ALIAS CGAL_Qt5_moc_and_resources) add_library(CGAL::Qt5_moc_and_resources ALIAS CGAL_Qt5_moc_and_resources) @@ -101,6 +117,6 @@ function(CGAL_setup_CGAL_Qt5_dependencies target) if(CGAL_HEADER_ONLY) target_link_libraries( ${target} ${keyword} CGAL::Qt5_moc_and_resources) endif() - target_link_libraries( ${target} ${keyword} Qt5::OpenGL Qt5::Svg) + target_link_libraries( ${target} ${keyword} Qt5::OpenGL Qt5::Svg Qt5::Xml) endfunction() diff --git a/Installation/cmake/modules/FindQGLViewer.cmake b/Installation/cmake/modules/FindQGLViewer.cmake deleted file mode 100644 index aadfa505689..00000000000 --- a/Installation/cmake/modules/FindQGLViewer.cmake +++ /dev/null @@ -1,81 +0,0 @@ -# - Try to find QGLViewer -# Once done this will define -# -# QGLVIEWER_FOUND - system has QGLViewer -# QGLVIEWER_INCLUDE_DIR - the QGLViewer include directory -# QGLVIEWER_LIBRARIES - Link these to use QGLViewer -# QGLVIEWER_DEFINITIONS - Compiler switches required for using QGLViewer -# -if(POLICY CMP0072) - # About the use of OpenGL - cmake_policy(SET CMP0072 NEW) -endif() -find_package(OpenGL QUIET) -find_package(Qt5 QUIET COMPONENTS OpenGL Xml) - -# first look in user defined locations -find_path(QGLVIEWER_INCLUDE_DIR - NAMES QGLViewer/qglviewer.h - NO_DEFAULT_PATH - PATHS ENV QGLVIEWERROOT - /usr/local/include - ) - -find_library(QGLVIEWER_LIBRARY_RELEASE - NAMES qglviewer-qt5 qglviewer QGLViewer-qt5 QGLViewer QGLViewer2-qt5 QGLViewer2 - NO_DEFAULT_PATH - PATHS ENV QGLVIEWERROOT - ENV LD_LIBRARY_PATH - ENV LIBRARY_PATH - /usr/local/lib - PATH_SUFFIXES QGLViewer QGLViewer/release - ) - -find_library(QGLVIEWER_LIBRARY_DEBUG - NAMES dqglviewer dQGLViewer-qt5 dQGLViewer dQGLViewer2-qt5 dQGLViewer2 QGLViewerd2-qt5 QGLViewerd2 - NO_DEFAULT_PATH - PATHS /usr/local/lib - ENV QGLVIEWERROOT - ENV LD_LIBRARY_PATH - ENV LIBRARY_PATH - PATH_SUFFIXES QGLViewer QGLViewer/debug - ) - -#now try the standard paths -if (NOT QGLVIEWER_INCLUDE_DIR OR NOT QGLVIEWER_LIBRARY_RELEASE OR NOT QGLVIEWER_LIBRARY_DEBUG) -find_path(QGLVIEWER_INCLUDE_DIR - NAMES QGLViewer/qglviewer.h) - -find_library(QGLVIEWER_LIBRARY_RELEASE - NAMES qglviewer-qt5 qglviewer QGLViewer-qt5 QGLViewer QGLViewer2-qt5 QGLViewer2) - -find_library(QGLVIEWER_LIBRARY_DEBUG - NAMES dqglviewer dQGLViewer-qt5 dQGLViewer dQGLViewer2-qt5 dQGLViewer2 QGLViewerd2-qt5 QGLViewerd2) - -endif() - -if(QGLVIEWER_LIBRARY_RELEASE) - if(QGLVIEWER_LIBRARY_DEBUG) - set(QGLVIEWER_LIBRARIES_ Qt5::Xml Qt5::OpenGL ${OPENGL_LIBRARIES} optimized ${QGLVIEWER_LIBRARY_RELEASE} debug ${QGLVIEWER_LIBRARY_DEBUG}) - else() - set(QGLVIEWER_LIBRARIES_ Qt5::Xml Qt5::OpenGL ${OPENGL_LIBRARIES} ${QGLVIEWER_LIBRARY_RELEASE}) - endif() - - set(QGLVIEWER_LIBRARIES ${QGLVIEWER_LIBRARIES_} CACHE FILEPATH "The QGLViewer library") - -endif() - -IF(QGLVIEWER_INCLUDE_DIR AND QGLVIEWER_LIBRARIES) - SET(QGLVIEWER_FOUND TRUE) -ENDIF(QGLVIEWER_INCLUDE_DIR AND QGLVIEWER_LIBRARIES) - -IF(QGLVIEWER_FOUND) - IF(NOT QGLViewer_FIND_QUIETLY) - MESSAGE(STATUS "Found QGLViewer: ${QGLVIEWER_LIBRARIES}") - ENDIF(NOT QGLViewer_FIND_QUIETLY) -ELSE(QGLVIEWER_FOUND) - IF(QGLViewer_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find QGLViewer") - ENDIF(QGLViewer_FIND_REQUIRED) -ENDIF(QGLVIEWER_FOUND) - diff --git a/Installation/cmake/modules/UseCGAL.cmake b/Installation/cmake/modules/UseCGAL.cmake index a11c5470c87..5128023cc5d 100644 --- a/Installation/cmake/modules/UseCGAL.cmake +++ b/Installation/cmake/modules/UseCGAL.cmake @@ -26,20 +26,6 @@ if(NOT USE_CGAL_FILE_INCLUDED) include(${CMAKE_CURRENT_LIST_DIR}/CGAL_GeneratorSpecificSettings.cmake) include(${CMAKE_CURRENT_LIST_DIR}/CGAL_TweakFindBoost.cmake) - set(CGAL_INSTALLED_SCM_BRANCH_NAME ${CGAL_SCM_BRANCH_NAME}) - set(CGAL_SCM_BRANCH_NAME "") - - if( NOT "${CGAL_INSTALLED_SCM_BRANCH_NAME}" STREQUAL "" ) - include(${CMAKE_CURRENT_LIST_DIR}/CGAL_SCM.cmake) - CGAL_detect_git(${CMAKE_SOURCE_DIR}) - if ( NOT "${CGAL_SCM_BRANCH_NAME}" STREQUAL "" ) - message ( STATUS "Code taken from Git branch: ${CGAL_SCM_BRANCH_NAME}" ) - if ( NOT "${CGAL_SCM_BRANCH_NAME}" STREQUAL "${CGAL_INSTALLED_SCM_BRANCH_NAME}") - message (AUTHOR_WARNING "Branch '${CGAL_SCM_BRANCH_NAME}' does not match branch '${CGAL_INSTALLED_SCM_BRANCH_NAME}' from which CGAL has been installed. Please consider rebuilding CGAL from this branch.") - endif() - endif() - endif() - set( CGAL_LIBRARIES ) foreach ( component ${CGAL_REQUESTED_COMPONENTS} ) diff --git a/Installation/cmake/modules/run_cmd_redirection_cerr.cmake b/Installation/cmake/modules/run_cmd_redirection_cerr.cmake index baaa2971452..40269e5b2c2 100644 --- a/Installation/cmake/modules/run_cmd_redirection_cerr.cmake +++ b/Installation/cmake/modules/run_cmd_redirection_cerr.cmake @@ -15,17 +15,26 @@ if(NOT CERR) "The variable `CERR` should be defined to the output error file!") endif() +# Create the file before using it +file(WRITE ${CERR}) + +# Execute the command ${CMD} with stderr redirected to the file ${CERR} execute_process( COMMAND ${CMD} - ERROR_VARIABLE err + ERROR_FILE "${CERR}" OUTPUT_VARIABLE output RESULT_VARIABLE error_result) -file(WRITE ${CERR} "${err}") - if(error_result) - string(REPLACE ";" " " CMD_STR "${CMD}") - message(SEND_ERROR + if(CMD2) + file(REMOVE ${CERR}) + execute_process(COMMAND ${CMD2}) + message(SEND_ERROR) + else() + file(READ ${CERR} err) + file(REMOVE ${CERR}) + string(REPLACE ";" " " CMD_STR "${CMD}") + message(SEND_ERROR "The command ${CMD_STR} > ${CERR} ended with the error code ${error_result}, @@ -34,4 +43,5 @@ ${output} and the following error output: ${err}" ) + endif() endif() diff --git a/Installation/include/CGAL/Cartesian_converter_fwd.h b/Installation/include/CGAL/Cartesian_converter_fwd.h new file mode 100644 index 00000000000..2e265bc205c --- /dev/null +++ b/Installation/include/CGAL/Cartesian_converter_fwd.h @@ -0,0 +1,42 @@ +// Copyright (C) 2018 GeometryFactory Sarl +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// + +#ifndef CGAL_CARTESIAN_CONVERTER_FWD_H +#define CGAL_CARTESIAN_CONVERTER_FWD_H + +/// \file Cartesian_converter_fwd.h +/// Forward declarations of the `Cartesian_converter` class. + +#ifndef DOXYGEN_RUNNING +namespace CGAL { + +namespace internal { +template < typename K1, typename K2 > +struct Default_converter; +}//internal + +template < class K1, class K2, + class Converter = typename internal::Default_converter::Type > +class Cartesian_converter; + +} // CGAL +#endif + +#endif /* CGAL_CARTESIAN_CONVERTER_FWD_H */ + + diff --git a/Installation/include/CGAL/Kernel_traits_fwd.h b/Installation/include/CGAL/Kernel_traits_fwd.h new file mode 100644 index 00000000000..0f7359e7b72 --- /dev/null +++ b/Installation/include/CGAL/Kernel_traits_fwd.h @@ -0,0 +1,33 @@ +// Copyright (C) 2018 GeometryFactory Sarl +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// + +#ifndef CGAL_KERNEL_TRAITS_FWD_H +#define CGAL_KERNEL_TRAITS_FWD_H + +/// \file Kernel_traits_fwd.h +/// Forward declarations of the `Kernel_traits` class. + +#ifndef DOXYGEN_RUNNING +namespace CGAL { + +template struct Kernel_traits; + +} // CGAL +#endif + +#endif // CGAL_KERNEL_TRAITS_FWD_H diff --git a/Installation/include/CGAL/config.h b/Installation/include/CGAL/config.h index 70cb2a2281f..7c3cde37f53 100644 --- a/Installation/include/CGAL/config.h +++ b/Installation/include/CGAL/config.h @@ -107,6 +107,17 @@ # define BOOST_TT_HAS_POST_INCREMENT_HPP_INCLUDED #endif +// Macro used by Boost Parameter. Mesh_3 needs at least 12, before the +// Boost Parameter headers are included: +// defines the value to 8, if it is not yet defined. +// The CGAL BGL properties mechanism includes +// , that includes +// , and maybe other Boost libraries may use +// Boost Parameter as well. +// That is why that is important to define that macro as early as possible, +// in +#define BOOST_PARAMETER_MAX_ARITY 12 + // The following header file defines among other things BOOST_PREVENT_MACRO_SUBSTITUTION #include #include diff --git a/Installation/include/CGAL/disable_warnings.h b/Installation/include/CGAL/disable_warnings.h index 6c180ab3514..587492aad9c 100644 --- a/Installation/include/CGAL/disable_warnings.h +++ b/Installation/include/CGAL/disable_warnings.h @@ -34,6 +34,7 @@ # pragma warning(disable: 4714) // function marked as __forceinline not inlined # pragma warning(disable: 4800) // forcing value to bool 'true' or 'false' (performance warning) # pragma warning(disable: 4913) // user defined binary operator ',' exists but no overload could convert all operands, default built-in binary operator ',' used +# pragma warning(disable: 4834) // discarding return value of function with 'nodiscard' attribute #endif diff --git a/Installation/include/CGAL/internal/deprecation_warning.h b/Installation/include/CGAL/internal/deprecation_warning.h index 3234f3b8e20..442e28a06f2 100644 --- a/Installation/include/CGAL/internal/deprecation_warning.h +++ b/Installation/include/CGAL/internal/deprecation_warning.h @@ -20,7 +20,7 @@ // Including this header will cause compilation to fail // if CGAL_NO_DEPRECATED_CODE is defined. If this is not the case, it will issue -// a warning during compilation unless CGAL_NO_DEPRECATION_WARNINGS. +// a warning during compilation, unless CGAL_NO_DEPRECATION_WARNINGS is defined. // CGAL_DEPRECATED_HEADER, CGAL_REPLACEMENT_HEADER, and // CGAL_DEPRECATED_MESSAGE_DETAILS can be defined @@ -56,11 +56,11 @@ # define CGAL_INTERNAL_DEPRECATED_MESSAGE_HEADERS \ CGAL_INTERNAL_DEPRECATED_MESSAGE_DEPRECATED_HEADER \ CGAL_INTERNAL_NO_DEPRECATED_CODE_MESSAGE \ - " Please use `" CGAL_REPLACEMENT_HEADER "` instead.\n" + " Please use `" CGAL_REPLACEMENT_HEADER "` instead. " #else # define CGAL_INTERNAL_DEPRECATED_MESSAGE_HEADERS \ CGAL_INTERNAL_DEPRECATED_MESSAGE_DEPRECATED_HEADER \ - CGAL_INTERNAL_NO_DEPRECATED_CODE_MESSAGE "\n" + CGAL_INTERNAL_NO_DEPRECATED_CODE_MESSAGE " " #endif // if more details are given, print them diff --git a/Installation/include/CGAL/internal/disable_deprecation_warnings_and_errors.h b/Installation/include/CGAL/internal/disable_deprecation_warnings_and_errors.h new file mode 100644 index 00000000000..46335e51f06 --- /dev/null +++ b/Installation/include/CGAL/internal/disable_deprecation_warnings_and_errors.h @@ -0,0 +1,30 @@ +// Copyright (c) 2018 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// Author: Mael Rouxel-Labbé + +// Some tests are explicitely used to check the sanity of deprecated code and should not +// give warnings/errors on plateforms that defined CGAL_NO_DEPRECATED_CODE CGAL-wide +// (or did not disable deprecation warnings). + +#if !defined(CGAL_NO_DEPRECATION_WARNINGS) + #define CGAL_NO_DEPRECATION_WARNINGS +#endif + +#if defined(CGAL_NO_DEPRECATED_CODE) + #undef CGAL_NO_DEPRECATED_CODE +#endif diff --git a/Installation/include/CGAL/license/GraphicsView.h b/Installation/include/CGAL/license/GraphicsView.h index beeac0d78bc..270df8f74ad 100644 --- a/Installation/include/CGAL/license/GraphicsView.h +++ b/Installation/include/CGAL/license/GraphicsView.h @@ -14,7 +14,7 @@ // // $URL$ // $Id$ -// SPDX-License-Identifier: LGPL-3.0+ +// SPDX-License-Identifier: GPL-3.0+ // // Author(s) : Andreas Fabri // diff --git a/Interpolation/doc/Interpolation/CGAL/interpolation_functions.h b/Interpolation/doc/Interpolation/CGAL/interpolation_functions.h index b92d04ad3f8..bee04da3b82 100644 --- a/Interpolation/doc/Interpolation/CGAL/interpolation_functions.h +++ b/Interpolation/doc/Interpolation/CGAL/interpolation_functions.h @@ -21,8 +21,8 @@ The class */ template< typename Map > struct Data_access - : public CGAL::unary_function > + : public CGAL::cpp98::unary_function > { public: diff --git a/Interpolation/include/CGAL/interpolation_functions.h b/Interpolation/include/CGAL/interpolation_functions.h index bdb62827b8e..3efe93387d3 100644 --- a/Interpolation/include/CGAL/interpolation_functions.h +++ b/Interpolation/include/CGAL/interpolation_functions.h @@ -36,8 +36,8 @@ namespace CGAL { // Functor class for accessing the function values/gradients template< class Map > struct Data_access - : public CGAL::unary_function > + : public CGAL::cpp98::unary_function > { typedef typename Map::mapped_type Data_type; typedef typename Map::key_type Key_type; diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index 1390d6a407b..4a4ec69e0bf 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include diff --git a/Kernel_23/doc/Kernel_23/CGAL/Bbox_2.h b/Kernel_23/doc/Kernel_23/CGAL/Bbox_2.h index 284cc4178fa..3f70437c5b5 100644 --- a/Kernel_23/doc/Kernel_23/CGAL/Bbox_2.h +++ b/Kernel_23/doc/Kernel_23/CGAL/Bbox_2.h @@ -95,6 +95,11 @@ updates `b` to be the bounding box of `b` and `c` and returns itself. */ Bbox_2& operator+=(const Bbox_2 &c); +/*! +dilates the bounding box by a specified number of ULP. +*/ +void dilate(int dist); + /// @} }; /* end Bbox_2 */ diff --git a/Kernel_23/doc/Kernel_23/CGAL/Bbox_3.h b/Kernel_23/doc/Kernel_23/CGAL/Bbox_3.h index 66d54449ae3..88d9f4dd426 100644 --- a/Kernel_23/doc/Kernel_23/CGAL/Bbox_3.h +++ b/Kernel_23/doc/Kernel_23/CGAL/Bbox_3.h @@ -109,6 +109,10 @@ updates `b` to be the bounding box of `b` and `c` and returns itself. */ Bbox_3& operator+=(const Bbox_3 &c); +/*! +dilates the bounding box by a specified number of ULP. +*/ +void dilate(int dist); /// @} }; /* end Bbox_3 */ diff --git a/Kernel_23/doc/Kernel_23/CGAL/Point_2.h b/Kernel_23/doc/Kernel_23/CGAL/Point_2.h index b18c6b4c8d7..e304a259393 100644 --- a/Kernel_23/doc/Kernel_23/CGAL/Point_2.h +++ b/Kernel_23/doc/Kernel_23/CGAL/Point_2.h @@ -196,8 +196,7 @@ returns the dimension (the constant 2). int dimension() const; /*! -returns a bounding box containing `p`. Note that bounding boxes -are not parameterized with whatsoever. +returns a bounding box containing `p`. */ Bbox_2 bbox() const; diff --git a/Kernel_23/doc/Kernel_23/CGAL/Weighted_point_2.h b/Kernel_23/doc/Kernel_23/CGAL/Weighted_point_2.h index 92e9fc8e70f..620f63ae66c 100644 --- a/Kernel_23/doc/Kernel_23/CGAL/Weighted_point_2.h +++ b/Kernel_23/doc/Kernel_23/CGAL/Weighted_point_2.h @@ -101,16 +101,6 @@ public: */ bool operator!=(const Weighted_point_2 &q) const; - /*! - translates the point by the vector `v`. - */ - Weighted_point_2& operator+=(const Vector_2 &v); - - /*! - translates the point by the vector -`v`. - */ - Weighted_point_2& operator-=(const Vector_2 &v); - /// @} /// \name Coordinate Access @@ -190,8 +180,7 @@ public: int dimension() const; /*! - returns a bounding box containing `p`. Note that bounding boxes - are not parameterized with whatsoever. + returns a bounding box containing `p`. */ Bbox_2 bbox() const; diff --git a/Kernel_23/doc/Kernel_23/CGAL/Weighted_point_3.h b/Kernel_23/doc/Kernel_23/CGAL/Weighted_point_3.h index 299f8c6bbc8..849fc10ee4a 100644 --- a/Kernel_23/doc/Kernel_23/CGAL/Weighted_point_3.h +++ b/Kernel_23/doc/Kernel_23/CGAL/Weighted_point_3.h @@ -61,7 +61,7 @@ public: /*! introduces a weighted point with coordinates `x`, `y`, `z` and weight `0`. */ - Weighted_point_3(const Kernel::FT& x, const Kernel::FT& y, const Kernel::FT& Z); + Weighted_point_3(const Kernel::FT& x, const Kernel::FT& y, const Kernel::FT& z); /// @} @@ -101,16 +101,6 @@ public: */ bool operator!=(const Weighted_point_3 &q) const; - /*! - translates the point by the vector `v`. - */ - Weighted_point_3& operator+=(const Vector_3 &v); - - /*! - translates the point by the vector -`v`. - */ - Weighted_point_3& operator-=(const Vector_3 &v); - /// @} /// \name Coordinate Access @@ -200,8 +190,7 @@ public: int dimension() const; /*! - returns a bounding box containing `p`. Note that bounding boxes - are not parameterized with whatsoever. + returns a bounding box containing `p`. */ Bbox_3 bbox() const; diff --git a/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h b/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h index 2cb3db219c7..b0e1bad6df4 100644 --- a/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h +++ b/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h @@ -5976,11 +5976,17 @@ public: */ Kernel::Point_3 operator()(const Kernel::Segment_3& s, const Kernel::Point_3& p); + + /*! + returns the point of `r` that is the closest to `p`. + */ + Kernel::Point_3 operator()(const Kernel::Ray_3& r, + const Kernel::Point_3& p); /*! returns the point of `t` that is the closest to `p`. */ - Kernel::Point_3 operator()(const Kernel::Triangle_3& h, + Kernel::Point_3 operator()(const Kernel::Triangle_3& t, const Kernel::Point_3& p); /// @} diff --git a/Kernel_23/include/CGAL/Bbox_2.h b/Kernel_23/include/CGAL/Bbox_2.h index fbcdef4760f..02292f28d32 100644 --- a/Kernel_23/include/CGAL/Bbox_2.h +++ b/Kernel_23/include/CGAL/Bbox_2.h @@ -30,6 +30,7 @@ #include #include #include +#include namespace CGAL { @@ -76,6 +77,7 @@ public: inline Bbox_2 operator+(const Bbox_2 &b) const; inline Bbox_2& operator+=(const Bbox_2 &b); + inline void dilate(int dist); }; inline @@ -156,7 +158,17 @@ Bbox_2::operator+=(const Bbox_2& b) rep[3] = (std::max)(ymax(), b.ymax()); return *this; } - +inline +void +Bbox_2::dilate(int dist) +{ + using boost::math::float_advance; + float_advance(rep[0],-dist); + float_advance(rep[1],-dist); + float_advance(rep[2],dist); + float_advance(rep[3],dist); +} + inline bool do_overlap(const Bbox_2 &bb1, const Bbox_2 &bb2) diff --git a/Kernel_23/include/CGAL/Bbox_3.h b/Kernel_23/include/CGAL/Bbox_3.h index a0d2ee29ac5..c58538095ee 100644 --- a/Kernel_23/include/CGAL/Bbox_3.h +++ b/Kernel_23/include/CGAL/Bbox_3.h @@ -31,6 +31,7 @@ #include #include #include +#include namespace CGAL { @@ -78,6 +79,8 @@ public: Bbox_3 operator+(const Bbox_3& b) const; Bbox_3& operator+=(const Bbox_3& b); + + void dilate(int dist); }; inline @@ -176,6 +179,20 @@ Bbox_3::operator+=(const Bbox_3& b) return *this; } +inline +void +Bbox_3::dilate(int dist) +{ + using boost::math::float_advance; + float_advance(rep[0],-dist); + float_advance(rep[1],-dist); + float_advance(rep[2],-dist); + float_advance(rep[3],dist); + float_advance(rep[4],dist); + float_advance(rep[5],dist); +} + + inline bool do_overlap(const Bbox_3& bb1, const Bbox_3& bb2) diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index 0ff0de5764b..ec0681875e5 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -2855,10 +2855,7 @@ namespace CommonKernelFunctors { const typename K::Segment_3& segment, const K& k) { - typedef typename K::Point_3 Point_3; - typename K::Construct_projected_point_3 projection = - k.construct_projected_point_3_object(); typename K::Is_degenerate_3 is_degenerate = k.is_degenerate_3_object(); typename K::Construct_vertex_3 vertex = @@ -2867,20 +2864,27 @@ namespace CommonKernelFunctors { if(is_degenerate(segment)) return vertex(segment, 0); - // Project query on segment supporting line - const Point_3 proj = projection(segment.supporting_line(), query); - - Point_3 closest_point_on_segment; - bool inside = is_inside_segment_3(proj,segment,closest_point_on_segment,k); - + if(segment.to_vector() * (query-segment.source()) <= 0) + return segment.source(); + if(segment.to_vector() * (query-segment.target()) >= 0) + return segment.target(); // If proj is inside segment, returns it - if ( inside ) - return proj; - - // Else returns the constructed point - return closest_point_on_segment; + return k.construct_projected_point_3_object()(segment.supporting_line(), query); } + typename K::Point_3 + operator()(const typename K::Point_3& query, + const typename K::Ray_3& ray, + const K& k) + { + if ( ray.to_vector() * (query-ray.source()) <= 0) + return ray.source(); + else + { + return k.construct_projected_point_3_object()(ray.supporting_line(), query); + } + } + // code for operator for plane and point is defined in // CGAL/Cartesian/function_objects.h and CGAL/Homogeneous/function_objects.h }; diff --git a/Kernel_23/include/CGAL/Kernel_traits.h b/Kernel_23/include/CGAL/Kernel_traits.h index e52020fcb47..dc5d38257c0 100644 --- a/Kernel_23/include/CGAL/Kernel_traits.h +++ b/Kernel_23/include/CGAL/Kernel_traits.h @@ -26,6 +26,7 @@ #ifndef CGAL_KERNEL_TRAITS_H #define CGAL_KERNEL_TRAITS_H +#include #include #include diff --git a/Kernel_23/include/CGAL/Weighted_point_3.h b/Kernel_23/include/CGAL/Weighted_point_3.h index cb828b93a99..16bf1e51c4b 100644 --- a/Kernel_23/include/CGAL/Weighted_point_3.h +++ b/Kernel_23/include/CGAL/Weighted_point_3.h @@ -93,62 +93,62 @@ public: : Rep(typename R::Construct_weighted_point_3()(Return_base_tag(), x, y, z)) {} - typename cpp11::result_of::type + typename cpp11::result_of::type point() const { return typename R::Construct_point_3()(*this); } - typename cpp11::result_of::type + typename cpp11::result_of::type weight() const { return typename R::Compute_weight_3()(*this); } - typename cpp11::result_of::type + typename cpp11::result_of::type x() const { return typename R::Compute_x_3()(point()); } - typename cpp11::result_of::type + typename cpp11::result_of::type y() const { return typename R::Compute_y_3()(point()); } - typename cpp11::result_of::type + typename cpp11::result_of::type z() const { return typename R::Compute_z_3()(point()); } - typename cpp11::result_of::type + typename cpp11::result_of::type hx() const { return R().compute_hx_3_object()(point()); } - typename cpp11::result_of::type + typename cpp11::result_of::type hy() const { return R().compute_hy_3_object()(point()); } - typename cpp11::result_of::type + typename cpp11::result_of::type hz() const { return R().compute_hz_3_object()(point()); } - typename cpp11::result_of::type + typename cpp11::result_of::type hw() const { return R().compute_hw_3_object()(point()); } - typename cpp11::result_of::type + typename cpp11::result_of::type cartesian(int i) const { CGAL_kernel_precondition( (i == 0) || (i == 1) || (i == 2) ); @@ -167,7 +167,7 @@ public: return hw(); } - typename cpp11::result_of::type + typename cpp11::result_of::type operator[](int i) const { return cartesian(i); diff --git a/Kernel_23/include/CGAL/internal/Projection_traits_3.h b/Kernel_23/include/CGAL/internal/Projection_traits_3.h index a66158b9301..67e2760cfe2 100644 --- a/Kernel_23/include/CGAL/internal/Projection_traits_3.h +++ b/Kernel_23/include/CGAL/internal/Projection_traits_3.h @@ -805,6 +805,7 @@ public: typedef typename Rp::Construct_scaled_vector_3 Construct_scaled_vector_2; typedef typename Rp::Construct_triangle_3 Construct_triangle_2; typedef typename Rp::Construct_line_3 Construct_line_2; + typedef typename Rp::Construct_bbox_3 Construct_bbox_2; struct Less_xy_2 { typedef bool result_type; @@ -989,6 +990,9 @@ public: Construct_line_2 construct_line_2_object() const {return Construct_line_2();} + Construct_bbox_2 construct_bbox_2_object() const + {return Construct_bbox_2();} + Compute_scalar_product_2 compute_scalar_product_2_object() const {return Compute_scalar_product_2();} diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_2.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_2.h index 6aad5a2786c..f9e69b8c284 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_2.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_2.h @@ -51,7 +51,7 @@ template bool _test_2(const R& r) { - return + return _test_cls_vector_2(r) && _test_fct_vector_2(r) && _test_cls_point_2(r) diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_weighted_point_2.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_weighted_point_2.h index bbdc904fab7..f7d41190673 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_weighted_point_2.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_cls_weighted_point_2.h @@ -45,7 +45,7 @@ bool _test_cls_weighted_point_2(const R& ) RT n2( 50 ); RT n4( 5); FT iw = -1; - + int int_w = 1; CGAL::Point_2 p0(n1, n2, n4); // constructions @@ -57,6 +57,7 @@ bool _test_cls_weighted_point_2(const R& ) CGAL::Weighted_point_2 wp4(iwp); // with R::Weighted_point_2 CGAL::Weighted_point_2 wp5(wp3); // with CGAL::Weighted_point_2< R > CGAL::Weighted_point_2 wp6(n1, n2); // with coordinates + CGAL::Weighted_point_2 wp7(p0, int_w); use(wp0); use(wp4); use(wp5); // assignement @@ -65,12 +66,18 @@ bool _test_cls_weighted_point_2(const R& ) std::cout << "."; // accessors - CGAL::Point_2 p1 = wp2.point(); + CGAL::Point_2 p1; + p1 = wp1.point(); + + p1 = wp2.point(); assert(p1 == p0); + + p1 = wp3.point(); FT w = wp3.weight(); assert(w == iw); - + w = wp7.weight(); + // no need to test the other operations as they use Point_2 operations (which // are tested in _test_cls_point_2.h) diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_constructions_3.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_constructions_3.h index 2c3ff790b01..72326c520a7 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_constructions_3.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_fct_constructions_3.h @@ -26,12 +26,13 @@ template bool -_test_fct_constructions_3(const R&) +_test_fct_constructions_3(const R& r) { typedef typename R::RT RT; typedef typename R::Point_3 Point; typedef typename R::Weighted_point_3 Weighted_point; typedef typename R::Segment_3 Segment; + typedef typename R::Ray_3 Ray; typedef typename R::Plane_3 Plane; typedef typename R::Vector_3 Vector; typedef typename R::Triangle_3 Triangle; @@ -129,6 +130,12 @@ _test_fct_constructions_3(const R&) assert( CGAL::weighted_circumcenter( wp000_b, wp100_b, wp010_b) == wp000_b); assert( CGAL::weighted_circumcenter( wp000_b, wp100_b, wp010_b, wp001_b) == wp000_b); + // projected point + Ray ray(Point(0,0,0), Point (1,1,0)); + Segment s(Point(0,0,0), Point (1,1,0)); + assert( r.construct_projected_point_3_object()(ray, Point(-1,0,0)) == Point(0,0,0)); + assert( r.construct_projected_point_3_object()(s, Point(-1,0,0)) == Point(0,0,0)); + assert( r.construct_projected_point_3_object()(s, Point(2,0,0)) == Point(1,1,0)); return true; } diff --git a/Linear_cell_complex/benchmark/Linear_cell_complex_2/CMakeLists.txt b/Linear_cell_complex/benchmark/Linear_cell_complex_2/CMakeLists.txt index 3baf4250adc..6eae9b0b136 100644 --- a/Linear_cell_complex/benchmark/Linear_cell_complex_2/CMakeLists.txt +++ b/Linear_cell_complex/benchmark/Linear_cell_complex_2/CMakeLists.txt @@ -48,11 +48,11 @@ SET(QT_USE_QTSVG TRUE) SET(QT_USE_QTXML TRUE ) INCLUDE(${QT_USE_FILE}) ADD_DEFINITIONS(${QT_DEFINITIONS}) -SET (CGoGN_EXT_INCLUDES ${CGoGN_EXT_INCLUDES} ${QT_INCLUDE_DIR} ${QGLVIEWER_INCLUDE_DIR} ) -SET (CGoGN_EXT_LIBS ${CGoGN_EXT_LIBS} ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES} ) +SET (CGoGN_EXT_INCLUDES ${CGoGN_EXT_INCLUDES} ${QT_INCLUDE_DIR} ) +SET (CGoGN_EXT_LIBS ${CGoGN_EXT_LIBS} ${QT_LIBRARIES} ) add_executable(cgogn_performance_2 performance_2.h cgogn_performance_2.h cgogn_performance_2.cpp) -target_link_libraries(cgogn_performance_2 algo assimp container nl topology utils Zinri z ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES} ) +target_link_libraries(cgogn_performance_2 algo assimp container nl topology utils Zinri z ${QT_LIBRARIES} ) # Performance_2 add_executable(performance_2 @@ -68,6 +68,6 @@ add_executable(performance_2 target_link_libraries(performance_2 ${CGAL_LIBRARIES} surface_mesh - algo assimp container nl topology utils Zinri z ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES} + algo assimp container nl topology utils Zinri z ${QT_LIBRARIES} ${OPENMESH_LIBRARIES} ) diff --git a/Linear_cell_complex/benchmark/Linear_cell_complex_3/CMakeLists.txt b/Linear_cell_complex/benchmark/Linear_cell_complex_3/CMakeLists.txt index e1a2e344722..9faf17e58ac 100644 --- a/Linear_cell_complex/benchmark/Linear_cell_complex_3/CMakeLists.txt +++ b/Linear_cell_complex/benchmark/Linear_cell_complex_3/CMakeLists.txt @@ -37,11 +37,11 @@ add_definitions(-DINCLUDE_TEMPLATES) # Performance_3 add_executable(performance_3 performance_3.cpp) add_dependencies(performance_3 OpenVolumeMesh) -target_link_libraries(performance_3 OpenVolumeMesh boost_timer boost_system ${CGAL_LIBRARIES} algo assimp container nl topology utils Zinri z xml2 ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES} ${MAP_VIEWER_LIBRARIES}) +target_link_libraries(performance_3 OpenVolumeMesh boost_timer boost_system ${CGAL_LIBRARIES} algo assimp container nl topology utils Zinri z xml2 ${QT_LIBRARIES} ${MAP_VIEWER_LIBRARIES}) # CGoGN add_executable(cgogn_performance_3 performance_3.h cgogn_performance_3.h cgogn_performance_3.cpp) -target_link_libraries(cgogn_performance_3 algo assimp container nl topology utils Zinri z xml2 ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES} ) +target_link_libraries(cgogn_performance_3 algo assimp container nl topology utils Zinri z xml2 ${QT_LIBRARIES} ) # LCC_3 add_executable(lcc_performance_3 performance_3.h lcc_performance_3.h lcc_performance_3.cpp) diff --git a/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt b/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt index 40b748a36ca..d774c81cc65 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt +++ b/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt @@ -40,19 +40,15 @@ include(${CGAL_USE_FILE}) find_package(Qt5 QUIET COMPONENTS Xml Script OpenGL Svg) -find_package(QGLViewer) +if ( NOT (CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND ) ) -if ( NOT (CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND AND - QGLVIEWER_FOUND) ) - - MESSAGE(STATUS "NOTICE: This demo requires CGAL, QGLViewer, " + MESSAGE(STATUS "NOTICE: This demo requires CGAL, " "and Qt5, and will not be compiled.") else() add_definitions(-DQT_NO_KEYWORDS) -include_directories(${QGLVIEWER_INCLUDE_DIR}) include_directories(BEFORE . ../../include/) # ui file, created wih Qt Designer @@ -62,7 +58,6 @@ qt5_wrap_ui(uis MainWindow.ui CreateMesh.ui CreateMenger.ui # qrc files (resources files, that contain icons, at least) qt5_add_resources (CGAL_Qt5_RESOURCE_FILES ./Linear_cell_complex_3.qrc) - add_executable(Linear_cell_complex_3_demo Linear_cell_complex_3_demo.cpp MainWindow.cpp Viewer.cpp Linear_cell_complex_3_subdivision.cpp @@ -73,8 +68,7 @@ add_executable(Linear_cell_complex_3_demo add_to_cached_list(CGAL_EXECUTABLE_TARGETS Linear_cell_complex_3_demo) target_link_libraries(Linear_cell_complex_3_demo PRIVATE - CGAL::CGAL CGAL::CGAL_Qt5 Qt5::Gui Qt5::OpenGL - ${QGLVIEWER_LIBRARIES} ) + CGAL::CGAL CGAL::CGAL_Qt5 Qt5::Gui Qt5::OpenGL) include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake) cgal_add_compilation_test(Linear_cell_complex_3_demo) diff --git a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp index a9207f1c214..a78780d3e78 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp +++ b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include "import_moka.h" @@ -1006,9 +1007,9 @@ double compute_angle3d(const Vector_3& v1, const Vector_3& v2) double a = CGAL::to_double( (v1*v2) / ( sqrt(v1.squared_length()) * sqrt(v2.squared_length()) ) ) ; - if (a < -1.0) return acos(-1.0)/M_PI*180.0; - else if (a > 1.0) return acos(1.0)/M_PI*180.0; - else return acos(a)/M_PI*180.0; + if (a < -1.0) return acos(-1.0)/CGAL_PI*180.0; + else if (a > 1.0) return acos(1.0)/CGAL_PI*180.0; + else return acos(a)/CGAL_PI*180.0; } void MainWindow::on_actionMerge_coplanar_faces_triggered() diff --git a/Linear_cell_complex/demo/Linear_cell_complex/Viewer.cpp b/Linear_cell_complex/demo/Linear_cell_complex/Viewer.cpp index 6eb833ab8d7..f84e2c5a6f2 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/Viewer.cpp +++ b/Linear_cell_complex/demo/Linear_cell_complex/Viewer.cpp @@ -24,8 +24,9 @@ #include #include #include +#include -#include +#include #include //Vertex source code @@ -105,7 +106,7 @@ const char fragment_source_p_l[] = }; Viewer::Viewer(QWidget* parent) - : QGLViewer(CGAL::Qt::createOpenGLContext(),parent), + : CGAL::QGLViewer(parent), wireframe(false), flatShading(true), edges(true), @@ -595,7 +596,7 @@ void Viewer::compute_elements() lcc.free_mark(markface); } -void Viewer::attrib_buffers(QGLViewer* viewer) +void Viewer::attrib_buffers(CGAL::QGLViewer* viewer) { QMatrix4x4 mvpMatrix; QMatrix4x4 mvMatrix; @@ -653,10 +654,10 @@ void Viewer::attrib_buffers(QGLViewer* viewer) void Viewer::sceneChanged() { compute_elements(); - this->camera()->setSceneBoundingBox(qglviewer::Vec(bb.xmin(), + this->camera()->setSceneBoundingBox(CGAL::qglviewer::Vec(bb.xmin(), bb.ymin(), bb.zmin()), - qglviewer::Vec(bb.xmax(), + CGAL::qglviewer::Vec(bb.xmax(), bb.ymax(), bb.zmax())); are_buffers_initialized = false; @@ -664,11 +665,7 @@ void Viewer::sceneChanged() if (m_previous_scene_empty) this->showEntireScene(); else -#if QGLVIEWER_VERSION >= 0x020700 this->update(); -#else - this->updateGL(); -#endif m_previous_scene_empty = scene->lcc->is_empty(); // for the next call to sceneChanged } @@ -735,7 +732,7 @@ void Viewer::init() restoreStateFromFile(); initializeOpenGLFunctions(); // Define 'Control+Q' as the new exit shortcut (default was 'Escape') - setShortcut(EXIT_VIEWER, Qt::CTRL+Qt::Key_Q); + setShortcut(CGAL::qglviewer::EXIT_VIEWER, Qt::CTRL+Qt::Key_Q); // Add custom key description (see keyPressEvent). setKeyDescription(Qt::Key_W, "Toggles wire frame display"); @@ -788,11 +785,7 @@ void Viewer::keyPressEvent(QKeyEvent *e) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); displayMessage("Filled faces."); } -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); -#endif } else if ((e->key()==Qt::Key_F) && (modifiers==Qt::NoButton)) { @@ -801,31 +794,22 @@ void Viewer::keyPressEvent(QKeyEvent *e) displayMessage("Flat shading."); else displayMessage("Gouraud shading."); -#if QGLVIEWER_VERSION >= 0x020700 + update(); -#else - updateGL(); -#endif + } else if ((e->key()==Qt::Key_E) && (modifiers==Qt::NoButton)) { edges = !edges; displayMessage(QString("Draw edges=%1.").arg(edges?"true":"false")); -#if QGLVIEWER_VERSION >= 0x020700 + update(); -#else - updateGL(); -#endif } else if ((e->key()==Qt::Key_V) && (modifiers==Qt::NoButton)) { vertices = !vertices; displayMessage(QString("Draw vertices=%1.").arg(vertices?"true":"false")); -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); -#endif } else if ((e->key()==Qt::Key_N) && (modifiers==Qt::NoButton)) { @@ -837,41 +821,25 @@ void Viewer::keyPressEvent(QKeyEvent *e) { size_edges+=.5; displayMessage(QString("Size of edges=%1.").arg(size_edges)); -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); -#endif } else if ((e->key()==Qt::Key_Minus) && (modifiers==Qt::KeypadModifier)) { if (size_edges>.5) size_edges-=.5; displayMessage(QString("Size of edges=%1.").arg(size_edges)); -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); -#endif } else if ((e->key()==Qt::Key_Plus) && (modifiers==(Qt::ShiftModifier|Qt::KeypadModifier))) { size_points+=.5; displayMessage(QString("Size of points=%1.").arg(size_points)); -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); -#endif } else if ((e->key()==Qt::Key_Minus) && (modifiers==(Qt::ShiftModifier|Qt::KeypadModifier))) { if (size_points>.5) size_points-=.5; displayMessage(QString("Size of points=%1.").arg(size_points)); -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); -#endif } else if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) { @@ -883,11 +851,7 @@ void Viewer::keyPressEvent(QKeyEvent *e) if (ambient.z()>1.) ambient.setZ(1.); displayMessage(QString("Light color=(%1 %2 %3)."). arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); -#endif } else if ((e->key()==Qt::Key_PageDown) && (modifiers==Qt::NoButton)) { @@ -899,11 +863,7 @@ void Viewer::keyPressEvent(QKeyEvent *e) if (ambient.z()<0.) ambient.setZ(0.); displayMessage(QString("Light color=(%1 %2 %3)."). arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); -#endif } else if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::ShiftModifier)) { @@ -911,11 +871,7 @@ void Viewer::keyPressEvent(QKeyEvent *e) if (ambient.x()>1.) ambient.setX(1.); displayMessage(QString("Light color=(%1 %2 %3)."). arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); -#endif } else if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::AltModifier)) { @@ -923,11 +879,7 @@ void Viewer::keyPressEvent(QKeyEvent *e) if (ambient.y()>1.) ambient.setY(1.); displayMessage(QString("Light color=(%1 %2 %3)."). arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); -#endif } else if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::ControlModifier)) { @@ -935,11 +887,7 @@ void Viewer::keyPressEvent(QKeyEvent *e) if (ambient.z()>1.) ambient.setZ(1.); displayMessage(QString("Light color=(%1 %2 %3)."). arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); -#endif } else if ((e->key()==Qt::Key_PageDown) && (modifiers==Qt::ShiftModifier)) { @@ -947,11 +895,7 @@ void Viewer::keyPressEvent(QKeyEvent *e) if (ambient.x()<0.) ambient.setX(0.); displayMessage(QString("Light color=(%1 %2 %3)."). arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); -#endif } else if ((e->key()==Qt::Key_PageDown) && (modifiers==Qt::AltModifier)) { @@ -959,11 +903,7 @@ void Viewer::keyPressEvent(QKeyEvent *e) if (ambient.y()<0.) ambient.setY(0.); displayMessage(QString("Light color=(%1 %2 %3)."). arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); -#endif } else if ((e->key()==Qt::Key_PageDown) && (modifiers==Qt::ControlModifier)) { @@ -971,14 +911,10 @@ void Viewer::keyPressEvent(QKeyEvent *e) if (ambient.z()<0.) ambient.setZ(0.); displayMessage(QString("Light color=(%1 %2 %3)."). arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); -#if QGLVIEWER_VERSION >= 0x020700 update(); -#else - updateGL(); -#endif } else - QGLViewer::keyPressEvent(e); + CGAL::QGLViewer::keyPressEvent(e); } QString Viewer::helpString() const diff --git a/Linear_cell_complex/demo/Linear_cell_complex/Viewer.h b/Linear_cell_complex/demo/Linear_cell_complex/Viewer.h index 7df6c376967..894ec46eaa3 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/Viewer.h +++ b/Linear_cell_complex/demo/Linear_cell_complex/Viewer.h @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include @@ -36,7 +36,7 @@ #define NB_VBO_BUFFERS 8 #define NB_VAO_BUFFERS 4 -class Viewer : public QGLViewer, public QOpenGLFunctions_2_1 +class Viewer : public CGAL::QGLViewer { Q_OBJECT @@ -66,7 +66,7 @@ public Q_SLOTS: private: void initialize_buffers(); - void attrib_buffers(QGLViewer*); + void attrib_buffers(CGAL::QGLViewer*); void compile_shaders(); void compute_elements(); diff --git a/Linear_cell_complex/doc/Linear_cell_complex/CGAL/draw_linear_cell_complex.h b/Linear_cell_complex/doc/Linear_cell_complex/CGAL/draw_linear_cell_complex.h new file mode 100644 index 00000000000..7fd78b6695f --- /dev/null +++ b/Linear_cell_complex/doc/Linear_cell_complex/CGAL/draw_linear_cell_complex.h @@ -0,0 +1,15 @@ +namespace CGAL { + +/*! +\ingroup PkgDrawLinearCellComplex + +Open a new window and draw `alcc`, a model of the `LinearCellComplex` concept. The function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. +\tparam LCC a model of the `LinearCellComplex` concept. +\param alcc the linear cell complex to draw. + +*/ +template +void draw(const LCC& alcc); + +} /* namespace CGAL */ + diff --git a/Linear_cell_complex/doc/Linear_cell_complex/Linear_cell_complex.txt b/Linear_cell_complex/doc/Linear_cell_complex/Linear_cell_complex.txt index 0f00181c9a7..30e3be293e6 100644 --- a/Linear_cell_complex/doc/Linear_cell_complex/Linear_cell_complex.txt +++ b/Linear_cell_complex/doc/Linear_cell_complex/Linear_cell_complex.txt @@ -241,7 +241,7 @@ point: 1 0 0, color: 19 Before applying the sew operation, the eight vertices of the first cube are colored by `1`, and the eight vertices of the second cube by `19`. After the sew operation, there are eight vertices which are merged two by two, and due to the average functor, the color of the four resulting vertices is now 10. Then we insert a vertex in the center of the common 2-cell between the two cubes. The coordinates of this vertex are initialized with the barycenter of the 2-cell (-1,0.5,0.5), and its color is not initialized by the method, thus we set its color manually by using the result of \link LinearCellComplex::insert_barycenter_in_cell `insert_barycenter_in_cell<2>`\endlink which is a dart incident to the new vertex. -\subsection Linear_cell_complexAutomaticAttributesManagement Automatic attributes management +\subsection Linear_cell_complexAutomaticAttributesManagement Automatic Attribute Management \anchor ssecAttributesManagement The following example illustrates the use of the automatic attributes management for a linear cell complex. An off file is loaded into a 2D linear cell complex embedded in 3D. Then, a certain percentage of edges is removed from the linear cell complex. The same method is applied twice: the first time by using the automatic attributes management (which is the default behaviour) and the second time by calling first \link GenericMap::set_automatic_attributes_management `set_automatic_attributes_management(false)`\endlink to disable the automatic updating of attributes. @@ -250,6 +250,19 @@ We can observe that the second run is faster than the first one. Indeed, updatin \cgalExample{Linear_cell_complex/linear_cell_complex_3_attributes_management.cpp} +\subsection Linear_cell_complexDraw Draw a Linear Cell Complex +\anchor ssecDrawLCC + +A linear cell complex can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given linear cell complex. The function is blocking, that is the program continues as soon as the user closes the window. + +\cgalExample{Linear_cell_complex/draw_linear_cell_complex.cpp} + +This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time. + +\cgalFigureBegin{fig_draw_lcc,draw_lcc.png} +Result of the run of the draw_linear_cell_complex program. A window shows two 3D cubes and allows to navigate through the 3D scene. +\cgalFigureEnd + \section Linear_cell_complexDesign Design and Implementation History This package was developed by Guillaume Damiand, with the help of Andreas Fabri, Sébastien Loriot and Laurent Rineau. Monique Teillaud and Bernd Gärtner contributed to the manual. diff --git a/Linear_cell_complex/doc/Linear_cell_complex/PackageDescription.txt b/Linear_cell_complex/doc/Linear_cell_complex/PackageDescription.txt index 4d9a112c79a..8eb6f42e7dc 100644 --- a/Linear_cell_complex/doc/Linear_cell_complex/PackageDescription.txt +++ b/Linear_cell_complex/doc/Linear_cell_complex/PackageDescription.txt @@ -19,6 +19,14 @@ /// \defgroup PkgLinearCellComplexOperations Operations for Linear Cell Complex /// \ingroup PkgLinearCellComplex +/*! Draw. + \code + #include + \endcode +*/ +/// \defgroup PkgDrawLinearCellComplex Draw a Linear Cell Complex +/// \ingroup PkgLinearCellComplex + /*! \addtogroup PkgLinearCellComplex @@ -57,14 +65,17 @@ - `CGAL::Linear_cell_complex` ## Global Functions ## -### Constructions for Linear cell complex ### +### Constructions for Linear Cell Complex ### - `CGAL::import_from_plane_graph` - `CGAL::import_from_triangulation_3` - `CGAL::import_from_polyhedron_3` -### Operations for Linear cell complex ### +### Operations for Linear Cell Complex ### - `CGAL::compute_normal_of_cell_0` - `CGAL::compute_normal_of_cell_2` +### Draw a Linear cell complex ### +- `CGAL::draw` + */ diff --git a/Linear_cell_complex/doc/Linear_cell_complex/examples.txt b/Linear_cell_complex/doc/Linear_cell_complex/examples.txt index 081c08d5da3..f41e9b41af0 100644 --- a/Linear_cell_complex/doc/Linear_cell_complex/examples.txt +++ b/Linear_cell_complex/doc/Linear_cell_complex/examples.txt @@ -3,4 +3,5 @@ \example Linear_cell_complex/linear_cell_complex_3.cpp \example Linear_cell_complex/linear_cell_complex_4.cpp \example Linear_cell_complex/linear_cell_complex_3_attributes_management.cpp +\example Linear_cell_complex/draw_linear_cell_complex.cpp */ diff --git a/Linear_cell_complex/doc/Linear_cell_complex/fig/draw_lcc.png b/Linear_cell_complex/doc/Linear_cell_complex/fig/draw_lcc.png new file mode 100644 index 00000000000..5ae0ccbb570 Binary files /dev/null and b/Linear_cell_complex/doc/Linear_cell_complex/fig/draw_lcc.png differ diff --git a/Linear_cell_complex/examples/Linear_cell_complex/CMakeBasicViewerQt.inc b/Linear_cell_complex/examples/Linear_cell_complex/CMakeBasicViewerQt.inc deleted file mode 100644 index 5dd94c1e7f9..00000000000 --- a/Linear_cell_complex/examples/Linear_cell_complex/CMakeBasicViewerQt.inc +++ /dev/null @@ -1,33 +0,0 @@ -# This file must be included in your CMakeLists.txt to use the basic viewer -# You need to link the libraries in your executable by using -# TARGET_LINK_LIBRARIES( myexec ${BASIC_VIEWER_LIBRARIES}) - -if ( NOT CGAL_FOUND OR NOT CGAL_Qt5_FOUND) - message(STATUS "NOTICE: Libraries for basic viewer not found " - "(CGAL, Qt5, QGLViewer).") -endif( NOT CGAL_FOUND OR NOT CGAL_Qt5_FOUND) - -include( ${CGAL_USE_FILE} ) -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -FIND_PACKAGE(Qt5 REQUIRED COMPONENTS OpenGL Xml) -find_package(QGLViewer REQUIRED) -find_package(OpenGL REQUIRED) - -add_definitions(${QT_DEFINITIONS}) -add_definitions(-DQT_NO_KEYWORDS) - -include_directories( ${QGLVIEWER_INCLUDE_DIR} ) -add_definitions(${QGLVIEWER_DEFINITIONS}) - -set (BASIC_VIEWER_LIBRARIES ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES} - ${OPENGL_gl_LIBRARY}) # ${OPENGL_glu_LIBRARY} - -set(BASIC_VIEWER_MODULES Xml OpenGL) - -ADD_DEFINITIONS("-DCGAL_USE_BASIC_VIEWER") -message(STATUS "Libraries for lcc_viewer found. You need to link them " - "in your executable by using " - "TARGET_LINK_LIBRARIES( myexec \${BASIC_VIEWER_LIBRARIES})") - -set(USE_BASIC_VIEWER true) diff --git a/Linear_cell_complex/examples/Linear_cell_complex/CMakeLists.txt b/Linear_cell_complex/examples/Linear_cell_complex/CMakeLists.txt index 0d26a50dbff..9c0372c277d 100644 --- a/Linear_cell_complex/examples/Linear_cell_complex/CMakeLists.txt +++ b/Linear_cell_complex/examples/Linear_cell_complex/CMakeLists.txt @@ -9,14 +9,11 @@ if(NOT POLICY CMP0070 AND POLICY CMP0053) cmake_policy(SET CMP0053 OLD) endif() -# If you want to visualize a linear cell complex, you can use the following viewer -# based on qt. Just uncomment the following two lines, plus the lines qt5_use_modules below +find_package(CGAL COMPONENTS Qt5) -# find_package(CGAL COMPONENTS Qt5) -# include("CMakeBasicViewerQt.inc") - -# If you don't want to visualize, use the following line (otherwise comment it) -find_package(CGAL QUIET) +if(CGAL_Qt5_FOUND) + add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS) +endif() # For Gprof. # ADD_DEFINITIONS("-pg") @@ -25,50 +22,31 @@ find_package(CGAL QUIET) # To use valgrind, we must disable rounding math ckeck. # add_definition(-DCGAL_DISABLE_ROUNDING_MATH_CHECK) -if ( CGAL_FOUND ) +if (CGAL_FOUND) include( ${CGAL_USE_FILE} ) - include( CGAL_CreateSingleSourceCGALProgram ) + include(CGAL_CreateSingleSourceCGALProgram) include_directories(BEFORE ../../include) - create_single_source_cgal_program( "linear_cell_complex_3.cpp" ) - create_single_source_cgal_program( "linear_cell_complex_4.cpp" ) - create_single_source_cgal_program( - "linear_cell_complex_3_with_colored_vertices.cpp" ) - create_single_source_cgal_program( - "linear_cell_complex_3_with_mypoint.cpp" ) - - create_single_source_cgal_program("plane_graph_to_lcc_2.cpp") + create_single_source_cgal_program("gmap_linear_cell_complex_3.cpp") + create_single_source_cgal_program("linear_cell_complex_3.cpp") create_single_source_cgal_program("linear_cell_complex_3_attributes_management.cpp") + create_single_source_cgal_program("linear_cell_complex_3_operations.cpp") + create_single_source_cgal_program("linear_cell_complex_3_with_colored_vertices.cpp") + create_single_source_cgal_program("linear_cell_complex_3_with_mypoint.cpp") + create_single_source_cgal_program("linear_cell_complex_4.cpp") + create_single_source_cgal_program("plane_graph_to_lcc_2.cpp") + create_single_source_cgal_program("voronoi_2.cpp") + create_single_source_cgal_program("voronoi_3.cpp") - add_executable(voronoi_2 voronoi_2.cpp) - target_link_libraries(voronoi_2 ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} - ${BASIC_VIEWER_LIBRARIES}) - if (USE_BASIC_VIEWER) - qt5_use_modules(voronoi_2 ${BASIC_VIEWER_MODULES}) - endif(USE_BASIC_VIEWER) + create_single_source_cgal_program("draw_linear_cell_complex.cpp") + if(CGAL_Qt5_FOUND) + target_link_libraries(draw_linear_cell_complex PUBLIC CGAL::CGAL_Qt5) + endif() - add_executable(voronoi_3 voronoi_3.cpp) - target_link_libraries(voronoi_3 ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} - ${BASIC_VIEWER_LIBRARIES}) - - if (USE_BASIC_VIEWER) - qt5_use_modules(voronoi_3 ${BASIC_VIEWER_MODULES}) - endif(USE_BASIC_VIEWER) - - create_single_source_cgal_program( "gmap_linear_cell_complex_3.cpp" ) - - add_executable(linear_cell_complex_3_operations linear_cell_complex_3_operations.cpp) - target_link_libraries(linear_cell_complex_3_operations ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} - ${BASIC_VIEWER_LIBRARIES}) - if (USE_BASIC_VIEWER) - qt5_use_modules(linear_cell_complex_3_operations ${BASIC_VIEWER_MODULES}) - endif(USE_BASIC_VIEWER) - else() - message(STATUS "This program requires the CGAL library, " - "and will not be compiled.") + message(STATUS "This program requires the CGAL library, and will not be compiled.") endif() diff --git a/Linear_cell_complex/examples/Linear_cell_complex/basic_viewer.h b/Linear_cell_complex/examples/Linear_cell_complex/basic_viewer.h index b992f7271b0..c9560733acd 100644 --- a/Linear_cell_complex/examples/Linear_cell_complex/basic_viewer.h +++ b/Linear_cell_complex/examples/Linear_cell_complex/basic_viewer.h @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include #include @@ -202,7 +202,7 @@ typename K::Vector_3 compute_normal_of_face(const std::vectorcamera()->setSceneBoundingBox(qglviewer::Vec(bb.xmin(), + this->camera()->setSceneBoundingBox(CGAL::qglviewer::Vec(bb.xmin(), bb.ymin(), bb.zmin()), - qglviewer::Vec(bb.xmax(), + CGAL::qglviewer::Vec(bb.xmax(), bb.ymax(), bb.zmax())); @@ -1127,7 +1127,7 @@ protected: updateGL(); } else - QGLViewer::keyPressEvent(e); + CGAL::QGLViewer::keyPressEvent(e); } virtual QString helpString() const diff --git a/Linear_cell_complex/examples/Linear_cell_complex/draw_linear_cell_complex.cpp b/Linear_cell_complex/examples/Linear_cell_complex/draw_linear_cell_complex.cpp new file mode 100644 index 00000000000..7888bba129d --- /dev/null +++ b/Linear_cell_complex/examples/Linear_cell_complex/draw_linear_cell_complex.cpp @@ -0,0 +1,29 @@ +#include +#include + +typedef CGAL::Linear_cell_complex_for_combinatorial_map<3> LCC; +typedef LCC::Dart_handle Dart_handle; +typedef LCC::Point Point; + +int main() +{ + LCC lcc; + Dart_handle dh1= + lcc.make_hexahedron(Point(0,0,0), Point(5,0,0), + Point(5,5,0), Point(0,5,0), + Point(0,5,4), Point(0,0,4), + Point(5,0,4), Point(5,5,4)); + Dart_handle dh2= + lcc.make_hexahedron(Point(5,0,0), Point(10,0,0), + Point(10,5,0), Point(5,5,0), + Point(5,5,4), Point(5,0,4), + Point(10,0,4), Point(10,5,4)); + + lcc.sew<3>(lcc.beta(dh1, 1, 1, 2), lcc.beta(dh2, 2)); + + lcc.display_characteristics(std::cout)<<", valid=" + < -struct Display_vol_vertices : public CGAL::unary_function +struct Display_vol_vertices : public CGAL::cpp98::unary_function { Display_vol_vertices(const LCC& alcc) : lcc(alcc), diff --git a/Linear_cell_complex/examples/Linear_cell_complex/linear_cell_complex_3.cpp b/Linear_cell_complex/examples/Linear_cell_complex/linear_cell_complex_3.cpp index 35e49a0d76f..15637a380ee 100644 --- a/Linear_cell_complex/examples/Linear_cell_complex/linear_cell_complex_3.cpp +++ b/Linear_cell_complex/examples/Linear_cell_complex/linear_cell_complex_3.cpp @@ -8,7 +8,7 @@ typedef LCC_3::Point Point; // Functor used to display all the vertices of a given volume. template -struct Display_vol_vertices : public CGAL::unary_function +struct Display_vol_vertices : public CGAL::cpp98::unary_function { Display_vol_vertices(const LCC& alcc) : lcc(alcc), diff --git a/Linear_cell_complex/examples/Linear_cell_complex/linear_cell_complex_3_operations.cpp b/Linear_cell_complex/examples/Linear_cell_complex/linear_cell_complex_3_operations.cpp index e5646197f9b..ce6c0735081 100644 --- a/Linear_cell_complex/examples/Linear_cell_complex/linear_cell_complex_3_operations.cpp +++ b/Linear_cell_complex/examples/Linear_cell_complex/linear_cell_complex_3_operations.cpp @@ -2,11 +2,6 @@ #include #include -/* If you want to use a viewer, you can use qglviewer. */ -#ifdef CGAL_USE_BASIC_VIEWER -#include "linear_cell_complex_3_viewer_qt.h" -#endif - typedef CGAL::Linear_cell_complex_for_combinatorial_map<3> LCC_3_cmap; typedef CGAL::Linear_cell_complex_for_generalized_map<3> LCC_3_gmap; @@ -54,10 +49,6 @@ void run_test() lcc.template sew<3>(lcc.template opposite<2>(lcc.next(dh1)), lcc.other_orientation(lcc.template opposite<2>(lcc.previous(dh3)))); -#ifdef CGAL_USE_BASIC_VIEWER - display_lcc(lcc); -#endif // CGAL_USE_BASIC_VIEWER - lcc.insert_cell_1_in_cell_2(lcc.next(dh1), Alpha1::run(lcc, lcc.previous(dh1))); dh2=lcc.template opposite<2>(lcc.next(lcc.next @@ -73,14 +64,9 @@ void run_test() lcc.insert_cell_2_in_cell_3(path.begin(),path.end()); lcc.display_characteristics(std::cout) << ", valid=" - << lcc.is_valid() << std::endl; - -#ifdef CGAL_USE_BASIC_VIEWER - display_lcc(lcc); -#endif // CGAL_USE_BASIC_VIEWER + << lcc.is_valid() << std::endl; } - int main() { run_test(); diff --git a/Linear_cell_complex/examples/Linear_cell_complex/linear_cell_complex_3_viewer_qt.h b/Linear_cell_complex/examples/Linear_cell_complex/linear_cell_complex_3_viewer_qt.h deleted file mode 100644 index 4e6d5e37077..00000000000 --- a/Linear_cell_complex/examples/Linear_cell_complex/linear_cell_complex_3_viewer_qt.h +++ /dev/null @@ -1,242 +0,0 @@ -// Copyright (c) 2011 CNRS and LIRIS' Establishments (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org); you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 3 of the License, -// or (at your option) any later version. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: LGPL-3.0+ -// -// Author(s) : Guillaume Damiand - -#ifndef CGAL_LCC_3_VIEWER_QT_H -#define CGAL_LCC_3_VIEWER_QT_H - -#include "basic_viewer.h" -#include -#include -#include - -typedef CGAL::Exact_predicates_inexact_constructions_kernel Local_kernel; -typedef Local_kernel::Point_3 Local_point; -typedef Local_kernel::Vector_3 Local_vector; - -// Default color functor; user can change it to have its own face color -struct DefaultColorFunctor -{ - template - static CGAL::Color run(const LCC& alcc, - typename LCC::Dart_const_handle dh) - { - if (dh==alcc.null_handle) // use to get the mono color - return CGAL::Color(100, 125, 200); // R G B between 0-255 - - // Here dh is the smaller dart of its face - CGAL::Random random(alcc.darts().index(dh)); - CGAL::Color res; - do - { - res=CGAL::Color(random.get_int(0,256), - random.get_int(0,256), - random.get_int(0,256)); - } - while(res.red()==255 && res.green()==255 && res.blue()==255); - return res; - } -}; - -template -struct Geom_utils; - -template -struct Geom_utils -{ - Local_point get_point(const LCC& lcc, - typename LCC::Vertex_attribute_const_handle vh) - { return converter(lcc.point_of_vertex_attribute(vh)); } - - Local_point get_point(const LCC& lcc, typename LCC::Dart_const_handle dh) - { return converter(lcc.point(dh)); } - - Local_vector get_vertex_normal(const LCC& lcc, - typename LCC::Dart_const_handle dh) - { - Local_vector n = converter(CGAL::compute_normal_of_cell_0(lcc,dh)); - n = n/(CGAL::sqrt(n*n)); - return n; - } -protected: - CGAL::Cartesian_converter converter; -}; - -template -struct Geom_utils -{ - Local_point get_point(const LCC& lcc, - typename LCC::Vertex_attribute_const_handle vh) - { - Local_point p(converter(lcc.point_of_vertex_attribute(vh).x()),0, - converter(lcc.point_of_vertex_attribute(vh).y())); - return p; - } - - Local_point get_point(const LCC& lcc, typename LCC::Dart_const_handle dh) - { return get_point(lcc, lcc.vertex_attribute(dh)); } - - Local_vector get_vertex_normal(const LCC&, typename LCC::Dart_const_handle) - { - Local_vector n(0,-1,0); - return n; - } -protected: - CGAL::Cartesian_converter converter; -}; - -// Viewer class for LCC -template -class SimpleLCCViewerQt : public Basic_viewer -{ - typedef Basic_viewer Base; - typedef typename LCC::Dart_const_handle Dart_const_handle; - -public: - /// Construct the viewer. - /// @param alcc the lcc to view - /// @param title the title of the window - /// @param anofaces if true, do not draw faces (faces are not computed; this can be - /// usefull for very big LCC where this time could be long) - SimpleLCCViewerQt(const LCC& alcc, const char* title="", bool anofaces=false) : - Base(title), - lcc(alcc), - m_nofaces(anofaces) - { - compute_elements(); - } - -protected: - - void compute_face(Dart_const_handle dh) - { - // We fill only closed faces. - Dart_const_handle cur=dh; - Dart_const_handle min=dh; - do - { - if (!lcc.is_next_exist(cur)) return; // open face=>not filled - if (cur(lcc, it, markfaces); - } - - if ( !lcc.is_marked(it, markedges) ) - { - compute_edge(it); - CGAL::mark_cell(lcc, it, markedges); - } - - if ( !lcc.is_marked(it, markvertices) ) - { - compute_vertex(it, empty); - CGAL::mark_cell(lcc, it, markvertices); - } - } - - lcc.free_mark(markfaces); - lcc.free_mark(markedges); - lcc.free_mark(markvertices); - } - - virtual void keyPressEvent(QKeyEvent *e) - { - const Qt::KeyboardModifiers modifiers = e->modifiers(); - Base::keyPressEvent(e); - } - -protected: - const LCC& lcc; - bool m_nofaces; - Geom_utils geomutils; -}; - - -template -void display_lcc(const LCC& alcc, - const char* title="", - bool nofill=false) -{ - int argc=1; - - const char* argv[2]={"lccviewer","\0"}; - QApplication app(argc,const_cast(argv)); - - SimpleLCCViewerQt mainwindow(alcc, title, nofill); - mainwindow.show(); - - app.exec(); -} - -#endif // CGAL_LCC_3_VIEWER_QT_H diff --git a/Linear_cell_complex/examples/Linear_cell_complex/voronoi_2.cpp b/Linear_cell_complex/examples/Linear_cell_complex/voronoi_2.cpp index 43ac93a3327..64fe08e3b42 100644 --- a/Linear_cell_complex/examples/Linear_cell_complex/voronoi_2.cpp +++ b/Linear_cell_complex/examples/Linear_cell_complex/voronoi_2.cpp @@ -6,10 +6,6 @@ #include #include -/* If you want to use a viewer, you can use qglviewer. */ -#ifdef CGAL_USE_BASIC_VIEWER -#include "linear_cell_complex_3_viewer_qt.h" -#endif // This example works both with cmap and gmap as combinatorial data structure. //typedef CGAL::Linear_cell_complex_for_combinatorial_map<2> LCC_2; @@ -56,10 +52,6 @@ void display_voronoi(LCC_2& alcc, Dart_handle adart) alcc.display_characteristics(std::cout) << ", valid=" << alcc.is_valid() << std::endl; - -#ifdef CGAL_USE_BASIC_VIEWER - display_lcc(alcc); -#endif // CGAL_USE_BASIC_VIEWER } template diff --git a/Linear_cell_complex/examples/Linear_cell_complex/voronoi_3.cpp b/Linear_cell_complex/examples/Linear_cell_complex/voronoi_3.cpp index 28bf93b0f12..30f94107b00 100644 --- a/Linear_cell_complex/examples/Linear_cell_complex/voronoi_3.cpp +++ b/Linear_cell_complex/examples/Linear_cell_complex/voronoi_3.cpp @@ -5,11 +5,6 @@ #include #include -/* If you want to use a viewer, you can use one qglviewer. */ -#ifdef CGAL_USE_BASIC_VIEWER -#include "linear_cell_complex_3_viewer_qt.h" -#endif - /* // If you want to use exact constructions. #include typedef CGAL::Linear_cell_complex<3,3, @@ -59,10 +54,6 @@ void display_voronoi(LCC_3& alcc, Dart_handle adart) alcc.display_characteristics(std::cout) << ", valid=" << alcc.is_valid() << std::endl; - -#ifdef CGAL_USE_BASIC_VIEWER - display_lcc(alcc); -#endif // CGAL_USE_BASIC_VIEWER } template diff --git a/Linear_cell_complex/include/CGAL/draw_linear_cell_complex.h b/Linear_cell_complex/include/CGAL/draw_linear_cell_complex.h new file mode 100644 index 00000000000..e792b745282 --- /dev/null +++ b/Linear_cell_complex/include/CGAL/draw_linear_cell_complex.h @@ -0,0 +1,247 @@ +// Copyright (c) 2018 CNRS and LIRIS' Establishments (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0+ +// +// Author(s) : Guillaume Damiand + +#ifndef CGAL_DRAW_LCC_H +#define CGAL_DRAW_LCC_H + +#include + +#ifdef CGAL_USE_BASIC_VIEWER + +#include + +namespace CGAL +{ + +// Default color functor; user can change it to have its own face color +struct DefaultColorFunctorLCC +{ + template + static CGAL::Color run(const LCC& alcc, + typename LCC::Dart_const_handle dh) + { + if (dh==alcc.null_handle) // use to get the mono color + return CGAL::Color(100, 125, 200); // R G B between 0-255 + + CGAL::Random random((unsigned int)(alcc.darts().index(dh))); + return get_random_color(random); + } +}; + +template +struct Geom_utils; + +template +struct Geom_utils +{ + static typename LCC::Vector get_vertex_normal(const LCC& lcc, + typename LCC::Dart_const_handle dh) + { + typename LCC::Vector n = CGAL::compute_normal_of_cell_0(lcc,dh); + n = n/(CGAL::sqrt(n*n)); + return n; + } +}; + +template +struct Geom_utils +{ + static typename LCC::Vector get_vertex_normal(const LCC&, + typename LCC::Dart_const_handle) + { + typename LCC::Vector res=CGAL::NULL_VECTOR; + return res; + } +}; + +// Viewer class for LCC +template +class SimpleLCCViewerQt : public Basic_viewer_qt +{ + typedef Basic_viewer_qt Base; + typedef typename LCC::Dart_const_handle Dart_const_handle; + typedef typename LCC::Traits Kernel; + typedef typename Kernel::Point Point; + typedef typename Kernel::Vector Vector; + +public: + /// Construct the viewer. + /// @param alcc the lcc to view + /// @param title the title of the window + /// @param anofaces if true, do not draw faces (faces are not computed; this can be + /// usefull for very big object where this time could be long) + SimpleLCCViewerQt(QWidget* parent, + const LCC& alcc, + const char* title="Basic LCC Viewer", + bool anofaces=false, + const ColorFunctor& fcolor=ColorFunctor()) : + // First draw: vertices; edges, faces; multi-color; inverse normal + Base(parent, title, true, true, true, false, true), + lcc(alcc), + m_nofaces(anofaces), + m_fcolor(fcolor) + { + compute_elements(); + } + +protected: + void compute_face(Dart_const_handle dh) + { + // We fill only closed faces. + Dart_const_handle cur=dh; + Dart_const_handle min=dh; + do + { + if (!lcc.is_next_exist(cur)) return; // open face=>not filled + if (cur::get_vertex_normal(lcc, cur)); + cur=lcc.next(cur); + } + while(cur!=dh); + + face_end(); + } + + void compute_edge(Dart_const_handle dh) + { + Point p1 = lcc.point(dh); + Dart_const_handle d2 = lcc.other_extremity(dh); + if (d2!=NULL) + { add_segment(p1, lcc.point(d2)); } + } + + void compute_vertex(Dart_const_handle dh) + { add_point(lcc.point(dh)); } + + void compute_elements() + { + clear(); + + typename LCC::size_type markfaces = lcc.get_new_mark(); + typename LCC::size_type markedges = lcc.get_new_mark(); + typename LCC::size_type markvertices = lcc.get_new_mark(); + + for (typename LCC::Dart_range::const_iterator it=lcc.darts().begin(), + itend=lcc.darts().end(); it!=itend; ++it ) + { + if ( !m_nofaces && !lcc.is_marked(it, markfaces) ) + { + compute_face(it); + CGAL::mark_cell(lcc, it, markfaces); + } + + if ( !lcc.is_marked(it, markedges) ) + { + compute_edge(it); + CGAL::mark_cell(lcc, it, markedges); + } + + if ( !lcc.is_marked(it, markvertices) ) + { + compute_vertex(it); + CGAL::mark_cell(lcc, it, markvertices); + } + } + + lcc.free_mark(markfaces); + lcc.free_mark(markedges); + lcc.free_mark(markvertices); + } + + virtual void keyPressEvent(QKeyEvent *e) + { + // Test key pressed: + // const ::Qt::KeyboardModifiers modifiers = e->modifiers(); + // if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) { ... } + + // Call: * compute_elements() if the model changed, followed by + // * redraw() if some viewing parameters changed that implies some + // modifications of the buffers + // (eg. type of normal, color/mono) + // * update() just to update the drawing + + // Call the base method to process others/classicals key + Base::keyPressEvent(e); + } + +protected: + const LCC& lcc; + bool m_nofaces; + const ColorFunctor& m_fcolor; +}; + +template +void draw(const LCC& alcc, + const char* title, + bool nofill, + const ColorFunctor& fcolor) +{ +#if defined(CGAL_TEST_SUITE) + bool cgal_test_suite=true; +#else + bool cgal_test_suite=false; +#endif + + if (!cgal_test_suite) + { + int argc=1; + const char* argv[2]={"lccviewer","\0"}; + QApplication app(argc,const_cast(argv)); + SimpleLCCViewerQt mainwindow(app.activeWindow(), + alcc, + title, + nofill, + fcolor); + mainwindow.show(); + app.exec(); + } +} + +template +void draw(const LCC& alcc, const char* title, bool nofill) +{ + DefaultColorFunctorLCC c; + draw(alcc, title, nofill, c); +} + +template +void draw(const LCC& alcc, const char* title) +{ draw(alcc, title, false); } + +template +void draw(const LCC& alcc) +{ draw(alcc, "Basic LCC Viewer"); } + +} // End namespace CGAL + +#endif // CGAL_USE_BASIC_VIEWER + +#endif // CGAL_DRAW_LCC_H diff --git a/Linear_cell_complex/package_info/Linear_cell_complex/dependencies b/Linear_cell_complex/package_info/Linear_cell_complex/dependencies index d3c90923a14..4a46d8312a8 100644 --- a/Linear_cell_complex/package_info/Linear_cell_complex/dependencies +++ b/Linear_cell_complex/package_info/Linear_cell_complex/dependencies @@ -8,6 +8,7 @@ Distance_2 Distance_3 Filtered_kernel Generalized_map +GraphicsView HalfedgeDS Hash_map Homogeneous_kernel diff --git a/Matrix_search/include/CGAL/sorted_matrix_search.h b/Matrix_search/include/CGAL/sorted_matrix_search.h index 287ae5b1a06..0a3eed4d325 100644 --- a/Matrix_search/include/CGAL/sorted_matrix_search.h +++ b/Matrix_search/include/CGAL/sorted_matrix_search.h @@ -125,7 +125,7 @@ private: }; template < class Cell > struct Cell_min -: public CGAL::unary_function< Cell, typename Cell::Value > +: public CGAL::cpp98::unary_function< Cell, typename Cell::Value > { typename Cell::Value operator()( const Cell& c) const @@ -134,7 +134,7 @@ struct Cell_min template < class Cell > struct Cell_max -: public CGAL::unary_function< Cell, typename Cell::Value > { +: public CGAL::cpp98::unary_function< Cell, typename Cell::Value > { Cell_max( int offset) : ofs( offset) {} diff --git a/Mesh_2/doc/Mesh_2/Mesh_2.txt b/Mesh_2/doc/Mesh_2/Mesh_2.txt index 7d6484b1f90..64012f69e97 100644 --- a/Mesh_2/doc/Mesh_2/Mesh_2.txt +++ b/Mesh_2/doc/Mesh_2/Mesh_2.txt @@ -98,11 +98,7 @@ printed. See \cgalFigureRef{Conformexampleconform} \cgalFigureBegin{Conformexampleconform,example-conform-Delaunay-Gabriel.png} -Initial triangulation and the corresponding Delaunay and Gabriel triangulation. -\cgalFigureEnd - -\cgalFigureBegin{ConformexampleconformDelaunay,example-conform-Delaunay.png} -The corresponding conforming Delaunay triangulation. +From left to right: Initial Delaunay triangulation, the corresponding conforming Delaunay, and the corresponding Gabriel triangulation. \cgalFigureEnd \section secMesh_2_meshes Meshes diff --git a/Mesh_2/doc/Mesh_2/fig/example-conform-Delaunay.png b/Mesh_2/doc/Mesh_2/fig/example-conform-Delaunay.png deleted file mode 100644 index 580db6feb3d..00000000000 Binary files a/Mesh_2/doc/Mesh_2/fig/example-conform-Delaunay.png and /dev/null differ diff --git a/Mesh_2/include/CGAL/Mesh_2/Clusters.h b/Mesh_2/include/CGAL/Mesh_2/Clusters.h index 9bf140dc531..42f59620685 100644 --- a/Mesh_2/include/CGAL/Mesh_2/Clusters.h +++ b/Mesh_2/include/CGAL/Mesh_2/Clusters.h @@ -118,8 +118,8 @@ private: typedef typename Cluster_map::value_type Cluster_map_value_type; template - struct Pair_get_first: public CGAL::unary_function + struct Pair_get_first + : public CGAL::cpp98::unary_function { typedef typename Pair::first_type result; const result& operator()(const Pair& p) const diff --git a/Mesh_2/include/CGAL/Mesh_2/Refine_edges.h b/Mesh_2/include/CGAL/Mesh_2/Refine_edges.h index 8bdddb618e8..983c552cc7f 100644 --- a/Mesh_2/include/CGAL/Mesh_2/Refine_edges.h +++ b/Mesh_2/include/CGAL/Mesh_2/Refine_edges.h @@ -635,7 +635,7 @@ protected: private: /** \name DEBUGGING TYPES AND DATAS */ class From_pair_of_vertex_to_edge - : public CGAL::unary_function + : public CGAL::cpp98::unary_function { Tr& tr; public: diff --git a/Mesh_2/include/CGAL/Mesh_2/Refine_faces.h b/Mesh_2/include/CGAL/Mesh_2/Refine_faces.h index a1da7301e30..7c4ef737e9d 100644 --- a/Mesh_2/include/CGAL/Mesh_2/Refine_faces.h +++ b/Mesh_2/include/CGAL/Mesh_2/Refine_faces.h @@ -385,8 +385,8 @@ class Refine_faces : typedef typename Tr::Geom_traits Geom_traits; template - struct Pair_get_first: public CGAL::unary_function + struct Pair_get_first + : public CGAL::cpp98::unary_function { typedef typename Pair::first_type result; const result& operator()(const Pair& p) const diff --git a/Mesh_2/include/CGAL/lloyd_optimize_mesh_2.h b/Mesh_2/include/CGAL/lloyd_optimize_mesh_2.h index 48b1457c19f..a5563bffc87 100644 --- a/Mesh_2/include/CGAL/lloyd_optimize_mesh_2.h +++ b/Mesh_2/include/CGAL/lloyd_optimize_mesh_2.h @@ -31,47 +31,19 @@ #include #include #include +#include +#include #include -#if ( defined( __clang__ ) || (BOOST_GCC >= 40600 ) ) && (BOOST_VERSION < 106000) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-variable" -#pragma GCC diagnostic ignored "-Wunused-parameter" -#endif - -#ifdef BOOST_PARAMETER_MAX_ARITY -# if (BOOST_PARAMETER_MAX_ARITY < 8) -# error "BOOST_PARAMETER_MAX_ARITY must be at least 8 for CGAL::lloyd_optimize_mesh_2()" -# endif -#else -# define BOOST_PARAMETER_MAX_ARITY 8 -#endif -#include -#include - -namespace CGAL -{ -namespace parameters -{ - - -BOOST_PARAMETER_NAME( cdt ) -BOOST_PARAMETER_NAME( (max_iteration_number, tag) max_iteration_number_ ) -BOOST_PARAMETER_NAME( (convergence, tag) convergence_) -BOOST_PARAMETER_NAME( (time_limit, tag) time_limit_ ) -BOOST_PARAMETER_NAME( (freeze_bound, tag) freeze_bound_) -BOOST_PARAMETER_NAME( (seeds_begin, tag) seeds_begin_) -BOOST_PARAMETER_NAME( (seeds_end, tag) seeds_end_) -BOOST_PARAMETER_NAME( (mark, tag) mark_) - -}//end namespace parameters -}//end namespace CGAL +// see +CGAL_PRAGMA_DIAG_PUSH +// see +CGAL_IGNORE_BOOST_PARAMETER_NAME_WARNINGS namespace CGAL { - using namespace parameters; #if defined(BOOST_MSVC) # pragma warning(push) @@ -81,7 +53,7 @@ namespace CGAL BOOST_PARAMETER_FUNCTION( (Mesh_optimization_return_code), lloyd_optimize_mesh_2, - tag, + parameters::tag, (required (in_out(cdt),*)) (optional (max_iteration_number_, *, 0 ) @@ -179,11 +151,7 @@ namespace CGAL } //end namespace CGAL -//CGAL_PRAGMA_DIAG_POP -#if ( defined( __clang__ ) || (BOOST_GCC >= 40600 ) ) && (BOOST_VERSION < 106000) -#pragma GCC diagnostic pop -#endif - +CGAL_PRAGMA_DIAG_POP #include diff --git a/Mesh_2/package_info/Mesh_2/dependencies b/Mesh_2/package_info/Mesh_2/dependencies index 8e839394994..a0eb105c10e 100644 --- a/Mesh_2/package_info/Mesh_2/dependencies +++ b/Mesh_2/package_info/Mesh_2/dependencies @@ -1,4 +1,5 @@ Algebraic_foundations +BGL Circulator Distance_2 Hash_map diff --git a/Mesh_3/doc/Mesh_3/CGAL/Gray_image_mesh_domain_3.h b/Mesh_3/doc/Mesh_3/CGAL/Gray_image_mesh_domain_3.h index ea5e789f463..34808a821d2 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Gray_image_mesh_domain_3.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Gray_image_mesh_domain_3.h @@ -3,6 +3,11 @@ namespace CGAL { /*! \ingroup PkgMesh_3Domains +\deprecated The class template `Gray_image_mesh_domain_3` is deprecated +since CGAL-4.13, in favor of the class template `Labeled_mesh_domain_3` and +its static function +`Labeled_mesh_domain_3::create_gray_image_mesh_domain()`. + The class `Gray_image_mesh_domain_3` implements a domain described by a 3D gray image. A 3D gray image is a grid of voxels, where each voxel is associated with a gray level value. @@ -24,8 +29,7 @@ length of the diagonal of the bounding box (in world coordinates) and \tparam Image is the type of the input image. -This parameter must be a model of the concept -`LabeledImage_3`. +This parameter must be `CGAL::Image_3`. \tparam BGT is a geometric traits class which provides the basic operations to implement diff --git a/Mesh_3/doc/Mesh_3/CGAL/Image_3.h b/Mesh_3/doc/Mesh_3/CGAL/Image_3.h new file mode 100644 index 00000000000..b973c7d2632 --- /dev/null +++ b/Mesh_3/doc/Mesh_3/CGAL/Image_3.h @@ -0,0 +1,23 @@ +namespace CGAL { + +/*! +\ingroup PkgMesh_3Domains + +The class `Image_3` is a C++ wrapper around the InrImage library. It holds a +shared pointer to a 3D image buffer. + +*/ +class Image_3 { +public: + + /// The default-constructor. The object is invalid until a call to `read()`. + Image_3(); + + /// Open an 3D image file. + /// + /// Returns `true` if the file was sucessfully loaded. + bool read(const char* file); + +}; +} /* end namespace CGAL */ diff --git a/Mesh_3/doc/Mesh_3/CGAL/Implicit_mesh_domain_3.h b/Mesh_3/doc/Mesh_3/CGAL/Implicit_mesh_domain_3.h index 500dd2736e3..d0cf46482b9 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Implicit_mesh_domain_3.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Implicit_mesh_domain_3.h @@ -3,6 +3,11 @@ namespace CGAL { /*! \ingroup PkgMesh_3Domains +\deprecated The class template `Implicit_mesh_domain_3` is deprecated +since CGAL-4.13, in favor of the class template `Labeled_mesh_domain_3` and +its static function +`Labeled_mesh_domain_3::create_implicit_mesh_domain()`. + The class `Implicit_mesh_domain_3` implements a domain whose bounding surface is described implicitly as the zero level set of a function. diff --git a/Mesh_3/doc/Mesh_3/CGAL/Implicit_to_labeling_function_wrapper.h b/Mesh_3/doc/Mesh_3/CGAL/Implicit_to_labeling_function_wrapper.h index 728883d04e2..f43c2f3a857 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Implicit_to_labeling_function_wrapper.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Implicit_to_labeling_function_wrapper.h @@ -18,7 +18,7 @@ The second one matches the locus of points satisfying f1(p)>0 and f2(p)<0 and f3 This parameter stands for a model of the concept ImplicitFunction described in the surface mesh generation package. The number types Function::FT and BGT::FT are required to match. -\sa `Implicit_mesh_domain_3`. +\sa `Labeled_mesh_domain_3`. */ template diff --git a/Mesh_3/doc/Mesh_3/CGAL/Labeled_image_mesh_domain_3.h b/Mesh_3/doc/Mesh_3/CGAL/Labeled_image_mesh_domain_3.h index 960db2cbf8c..fddfbf0dfe6 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Labeled_image_mesh_domain_3.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Labeled_image_mesh_domain_3.h @@ -3,6 +3,11 @@ namespace CGAL { /*! \ingroup PkgMesh_3Domains +\deprecated The class template `Labeled_image_mesh_domain_3` is deprecated +since CGAL-4.13, in favor of the class template `Labeled_mesh_domain_3` and +its static function +`Labeled_mesh_domain_3::create_labeled_image_mesh_domain()`. + The class `Labeled_image_mesh_domain_3` implements a domain described by a 3D labeled image. A 3D labeled image is a grid of voxels, where each voxel is associated with an index (a subdomain index) characterizing the subdomain in which the voxel lies. This @@ -21,8 +26,7 @@ length of the diagonal of the bounding box (in world coordinates) and \tparam Image is the type of the input image. -This parameter must be a model of the concept -`LabeledImage_3`. +This parameter must be `CGAL::Image_3`. \tparam BGT is a geometric traits class which provides the basic operations to implement diff --git a/Mesh_3/doc/Mesh_3/CGAL/Labeled_mesh_domain_3.h b/Mesh_3/doc/Mesh_3/CGAL/Labeled_mesh_domain_3.h index 8755edeeb8c..2e76323ba42 100644 --- a/Mesh_3/doc/Mesh_3/CGAL/Labeled_mesh_domain_3.h +++ b/Mesh_3/doc/Mesh_3/CGAL/Labeled_mesh_domain_3.h @@ -11,7 +11,7 @@ Any boundary facet is labeled , a, where b!=0. -This class includes a function that provides, the subdomain index of any +This class includes a labeling function that provides, the subdomain index of any query point. An intersection between a segment and bounding surfaces is detected when both segment endpoints are associated with different values of subdomain indices. The intersection is then constructed by bisection. @@ -20,18 +20,13 @@ The bisection stops when the query segment is shorter than an error bound length of the diagonal of the bounding box (in world coordinates), or the radius of the bounding sphere, and a relative error bound passed as argument to the constructor of `Labeled_mesh_domain_3`. -Implicit_mesh_domain_3 is a heir of Labeled_mesh_domain_3. It uses a satisfying labeling function if there is only one component to mesh. - -\tparam LabelingFunction is the type of the input function.
-This parameter stands for a model of the concept ImplicitFunction described in the surface mesh generation package.
-Labeling function f must return 0 if the point isn't located in any subdomain. Usually, the return type of labeling functions are integer.
-Let p be a Point. +This class has a constructor taking a labeling function. It has also three +static template member functions that act as named constructors:
    -
  • f(p)=0 means that p is outside domain.
  • -
  • f(p)=a, a!=0 means that p is inside subdomain a.
  • +
  • `create_gray_image_mesh_domain()`, to create a domain from a 3D gray image, +
  • `create_labeled_image_mesh_domain()`, to create a domain from a 3D labeled image, and +
  • `create_implicit_mesh_domain()`, to create a domain from an implicit function.
-Implicit_multi_domain_to_labeling_function_wrapper is a good candidate for this template parameter -if there are several components to mesh. \tparam BGT is a geometric traits class that provides the basic operations to implement @@ -39,19 +34,229 @@ intersection tests and intersection computations through a bisection method. This parameter must be instantiated with a model of the concept `BisectionGeometricTraits_3`. +\cgalHeading{Labeling function} + +A labeling function `f` must return `0` if the point isn't located in any subdomain. The return type of labeling functions is an integer. + +Let `p` be a Point. +
    +
  • `f(p)=0` means that `p` is outside domain.
  • +
  • `f(p)=a`, `a!=0` means that `p` is inside subdomain `a`.
  • +
+`CGAL::Implicit_multi_domain_to_labeling_function_wrapper` is a good candidate for this template parameter +if there are several components to mesh. + +The function type can be any model of the concept `Callable` compatible with the signature `Subdomain_index(const Point_3&)`: it can be a function, a function object, a lambda expression... that takes a `%Point_3` as argument, and returns a type convertible to `Subdomain_index`. + \cgalModels MeshDomain_3 -\sa `Implicit_mesh_domain_3` \sa `Implicit_multi_domain_to_labeling_function_wrapper` \sa `CGAL::make_mesh_3()`. */ -template +template class Labeled_mesh_domain_3 { public: -/// \name Creation +/// \name Types +///@{ + +/// The subdomain index of this model of `MeshDomain_3`. +typedef int Subdomain_index; + +/// The type of object that stores the function using type-erasure +typedef CGAL::cpp11::function Labeling_function; + +///@} +/// \name Types imported from the geometric traits class +///@{ + +/// The point type of the geometric traits class +typedef typename Geom_traits::Point_3 Point_3; +/// The sphere type of the geometric traits class +typedef typename Geom_traits::Sphere_3 Sphere_3; +/// The iso-cuboid type of the geometric traits class +typedef typename Geom_traits::Iso_cuboid_3 Iso_cuboid_3; +/// The number type (a field type) of the geometric traits class +typedef typename Geom_traits::FT FT; +///@} + +/// \name Creation +/// @{ +/*! \brief Construction from a function, a bounding +object and a relative error bound. + +This constructor uses named parameters (from the Boost Parameter +Library). They can be specified in any order. + +\cgalHeading{Named Parameters} +- `parameters::function` (mandatory) the labeling function, compatible with `Labeling_function`. +- `parameters::bounding_object` (mandatory) the bounding object is either a bounding sphere (of type `Sphere_3`), a bounding box (type `Bbox_3`), or a bounding `Iso_cuboid_3`. It bounds the meshable space. +- `parameters::relative_error_bound` (optional) the relative error bound used to compute intersection points between the implicit surface and query segments. The +bisection is stopped when the length of the intersected segment is less than the product of `relative_error_bound` by the diameter of the bounding object. Its default value is `FT(1e-3)`. + +\cgalHeading{Example} +From the example (\ref Mesh_3/mesh_implicit_domains_2.cpp): +\snippet Mesh_3/mesh_implicit_domains_2.cpp Domain creation + + */ +template +Labeled_mesh_domain_3(const A_i&...); + +///@} + +/// \name Creation of domains from implicit functions + +/*! +\brief Construction from an implicit function + +This static method is a named constructor. It constructs a domain +whose bounding surface is described implicitly as the zero level set of a +function. The domain to be discretized is assumed to be the domain where +the function has negative values. + +The method takes as argument a bounding sphere which is required to +circumscribe the surface and to have its center inside the domain. + +This constructor uses named parameters (from the Boost Parameter +Library). They can be specified in any order. + +\cgalHeading{Named Parameters} +
    +
  • `parameters::function` (mandatory) the implicit function, +compatible with the signature `FT(Point_3)`: it takes a point as argument, +and returns a scalar value. That object must be model of `CopyConstructible`. +
  • `parameters::bounding_object` (mandatory) the bounding object is +either a bounding sphere (of type `Sphere_3`), a bounding box (type +`Bbox_3`), or a bounding `Iso_cuboid_3`. It must bounds the surface, and +its center must be inside the domain. +
+ +\cgalHeading{Examples} + +From the example (\ref Mesh_3/mesh_implicit_sphere.cpp), where the name of +the parameters is not specified, as they are given is the same order as the +parameters definition: + +\snippet Mesh_3/mesh_implicit_sphere.cpp Domain creation + +From the example (\ref Mesh_3/mesh_implicit_sphere_variable_size.cpp): + +\snippet Mesh_3/mesh_implicit_sphere_variable_size.cpp Domain creation + + */ +template +static +Labeled_mesh_domain_3 +create_implicit_mesh_domain(A_i&...); + +/// \name Creation of domains from 3D images + + +/*! +\brief Construction from a 3D gray image + +This static method is a named constructor. It constructs a domain +described by a 3D gray image. A 3D gray image is a grid of voxels, +where each voxel is associated with a gray level value. Unless otherwise specified by the parameter `image_values_to_subdom_indices`, the domain to +be discretized is the union of voxels that lie inside a surface +described by an isolevel value, called \a isovalue. The voxels lying +inside the domain have gray level values that are larger than the +isovalue. + +The value of voxels is interpolated to a gray level value at any query point. + +This constructor uses named parameters (from the Boost Parameter +Library). They can be specified in any order. + +\cgalHeading{Named Parameters} +The parameters are optional unless otherwise specified. +
    + +
  • `parameters::image` (mandatory) the input 3D image. Must +be a `CGAL::Image_3` object. + +
  • `parameters::iso_value` the isovalue, inside + `image`, of the surface describing the boundary of the object to be + meshed. Its default value is `0`. + +
  • `parameters::image_values_to_subdom_indices` a function or + a function object, compatible with the signature + `Subdomain_index(double)`. This function returns the subdomain index + corresponding to a pixel value. If this parameter is used, then the + parameter `iso_value` is ignored. + +
  • `parameter::value_outside` the value attached to voxels + outside of the domain to be meshed. It should be lower than + `iso_value`. Its default value is `0`. + +
  • `parameter::relative_error_bound` is the relative error + bound, relative to the diameter of the box of the image. Its default + value is `FT(1e-3)`.
+ +\cgalHeading{Examples} + +From the example (\ref Mesh_3/mesh_3D_gray_image.cpp), where the name +of the parameters is not specified, as they are given is the same +order as the parameters definition: + +\snippet Mesh_3/mesh_3D_gray_image.cpp Domain creation + +From the example (\ref Mesh_3/mesh_3D_gray_vtk_image.cpp): + +\snippet Mesh_3/mesh_3D_gray_vtk_image.cpp Domain creation + + */ +template +static +Labeled_mesh_domain_3 +create_gray_image_mesh_domain(A_i&...); + +/*! +\brief Construction from a 3D labeled image + +This static method is a named constructor. It constructs a +domain described by a 3D labeled image. A 3D labeled image is a grid +of voxels, where each voxel is associated with an index (a subdomain +index) characterizing the subdomain in which the voxel lies. The +domain to be discretized is the union of voxels that have non-zero +values. + +This constructor uses named parameters (from the Boost Parameter +Library). They can be specified in any order. + +\cgalHeading{Named Parameters} +The parameters are optional unless otherwise specified. +
    + +
  • `parameters::image` (mandatory) the input 3D image. Must +be a `CGAL::Image_3` object. + +
  • `parameter::value_outside` the value attached to voxels + outside of the domain to be meshed. Its default value is `0`. + +
  • `parameter::relative_error_bound` is the relative error + bound, relative to the diameter of the box of the image. Its default + value is `FT(1e-3)`.
+ +\cgalHeading{Example} + +From the example (\ref Mesh_3/mesh_3D_image.cpp): + +\snippet Mesh_3/mesh_3D_image.cpp Domain creation + + */ +template +static +Labeled_mesh_domain_3 +create_labeled_image_mesh_domain(A_i&...); + +/// \name Deprecated constructors +/// +/// Those three constructors have been deprecated since CGAL-4.13, and +/// replaced by the constructor using the Boost Parameter Library. +/// /// @{ /*! @@ -61,8 +266,10 @@ public: \param relative_error_bound is the relative error bound used to compute intersection points between the implicit surface and query segments. The bisection is stopped when the length of the intersected segment is less than the product of `relative_error_bound` by the radius of `bounding_sphere`. +\deprecated This constructor is deprecated since CGAL-4.13, and +replaced by the constructor using the Boost Parameter Library. */ -Labeled_mesh_domain_3(const LabelingFunction& f, +Labeled_mesh_domain_3(Labeling_function f, const Sphere_3& bounding_sphere, const FT& relative_error_bound = FT(1e-3)); @@ -73,8 +280,10 @@ Labeled_mesh_domain_3(const LabelingFunction& f, \param relative_error_bound is the relative error bound used to compute intersection points between the implicit surface and query segments. The bisection is stopped when the length of the intersected segment is less than the product of `relative_error_bound` by the diagonal of `bounding_box`. +\deprecated This constructor is deprecated since CGAL-4.13, and +replaced by the constructor using the Boost Parameter Library. */ -Labeled_mesh_domain_3(const LabelingFunction& f, +Labeled_mesh_domain_3(Labeling_function f, const Bbox_3& bbox, const FT& relative_error_bound = FT(1e-3)); @@ -85,8 +294,10 @@ Labeled_mesh_domain_3(const LabelingFunction& f, \param relative_error_bound is the relative error bound used to compute intersection points between the implicit surface and query segments. The bisection is stopped when the length of the intersected segment is less than the product of `relative_error_bound` by the diagonal of `bounding_box`. +\deprecated This constructor is deprecated since CGAL-4.13, and +replaced by the constructor using the Boost Parameter Library. */ -Labeled_mesh_domain_3(const LabelingFunction& f, +Labeled_mesh_domain_3(Labeling_function f, const Iso_cuboid_3& bbox, const FT& relative_error_bound = FT(1e-3)); diff --git a/Mesh_3/doc/Mesh_3/Concepts/BisectionGeometricTraits_3.h b/Mesh_3/doc/Mesh_3/Concepts/BisectionGeometricTraits_3.h index 4c55a49fe2d..af8ade1a8f0 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/BisectionGeometricTraits_3.h +++ b/Mesh_3/doc/Mesh_3/Concepts/BisectionGeometricTraits_3.h @@ -20,8 +20,7 @@ of the segment. \sa `ImplicitSurfaceTraits_3` \sa `IntersectionGeometricTraits_3` -\sa `CGAL::Implicit_mesh_domain_3` -\sa `CGAL::Labeled_image_mesh_domain_3` +\sa `CGAL::Labeled_mesh_domain_3` */ diff --git a/Mesh_3/doc/Mesh_3/Concepts/LabeledImage_3.h b/Mesh_3/doc/Mesh_3/Concepts/LabeledImage_3.h deleted file mode 100644 index 627cefdc5ad..00000000000 --- a/Mesh_3/doc/Mesh_3/Concepts/LabeledImage_3.h +++ /dev/null @@ -1,80 +0,0 @@ -/*! -\ingroup PkgMesh_3SecondaryConcepts -\cgalConcept - -The concept `LabeledImage_3` describes the requirements for the second template -parameter of the class `CGAL::Labeled_image_mesh_domain_3` -which represents mesh domains defined by 3D labeled images. A 3D labeled -image is a 3D array of elements of an integral -type `Type`. `Type` can be `bool`, `char`, `short`, -`int`, or `long` (signed or not). Such an array is -associated to a 3D axis-aligned regular grid, in -\f$ \mathbb{R}^3\f$. A cell of this grid is denoted by voxel. A voxel is -an iso-cuboid of size `vx()`, `vy()`, and `vz()`. - -\cgalHasModel `CGAL::Image_3`, for any \cgal kernel `K` and any integral type `T` - -*/ - -class LabeledImage_3 { -public: - -/// \name Types -/// @{ - -/*! -Type of voxel data. Must be an -integral type. -*/ -typedef unspecified_type Type; - -/*! -Ring number type. -*/ -typedef unspecified_type RT; - -/// @} - -/// \name Operations -/// @{ - -/*! -First dimension of the 3D array, -i.e., the number of voxels along the x coordinate axis. -*/ -int xdim(); - -/*! -Second dimension of the 3D array. -*/ -int ydim(); - -/*! -Third dimension of the 3D array. -*/ -int zdim(); - -/*! -Size of each voxel along x coordinate axis. -*/ -RT vx(); - -/*! -Size of each voxel along y coordinate axis. -*/ -RT vy(); - -/*! -Size of each voxel along z coordinate axis. -*/ -RT vz(); - -/*! -Pointer to the first element of the 3D -image. The size of the array must be `xdim()`\f$ \times\f$`ydim()`\f$ \times\f$`zdim()`. -*/ -const Type* data(); - -/// @} - -}; /* end LabeledImage_3 */ diff --git a/Mesh_3/doc/Mesh_3/Concepts/MeshDomain_3.h b/Mesh_3/doc/Mesh_3/Concepts/MeshDomain_3.h index 23923535102..60205e189bc 100644 --- a/Mesh_3/doc/Mesh_3/Concepts/MeshDomain_3.h +++ b/Mesh_3/doc/Mesh_3/Concepts/MeshDomain_3.h @@ -30,9 +30,7 @@ if it includes points which are strictly inside and strictly outside the domain (resp. the subdomain). \cgalHasModel `CGAL::Polyhedral_mesh_domain_3` -\cgalHasModel `CGAL::Implicit_mesh_domain_3` -\cgalHasModel `CGAL::Labeled_image_mesh_domain_3` -\cgalHasModel `CGAL::Labeled_mesh_domain_3` +\cgalHasModel `CGAL::Labeled_mesh_domain_3` \sa `MeshVertexBase_3` \sa `MeshCellBase_3` diff --git a/Mesh_3/doc/Mesh_3/Mesh_3.txt b/Mesh_3/doc/Mesh_3/Mesh_3.txt index d682deb13eb..07fc6d487ea 100644 --- a/Mesh_3/doc/Mesh_3/Mesh_3.txt +++ b/Mesh_3/doc/Mesh_3/Mesh_3.txt @@ -881,9 +881,9 @@ image is composed of 1D curves, and must be defined as 1D-features in the domain. The first modification is the type of the mesh domain. Instead of being -`Labeled_image_mesh_domain_3`, it is a +`Labeled_mesh_domain_3`, it is a `Mesh_domain_with_polyline_features_3` templated by a -`Labeled_image_mesh_domain_3`. +`Labeled_mesh_domain_3`. \snippet Mesh_3/mesh_3D_image_with_features.cpp Domain definition diff --git a/Mesh_3/doc/Mesh_3/PackageDescription.txt b/Mesh_3/doc/Mesh_3/PackageDescription.txt index aecb0b2b3ba..a823b21cffc 100644 --- a/Mesh_3/doc/Mesh_3/PackageDescription.txt +++ b/Mesh_3/doc/Mesh_3/PackageDescription.txt @@ -70,7 +70,6 @@ related to the template parameters of some models of the main concepts: - `BisectionGeometricTraits_3` - `IntersectionGeometricTraits_3` -- `LabeledImage_3` - `MeshCellBase_3` - `MeshVertexBase_3` - `MeshDomainField_3` @@ -93,17 +92,17 @@ related to the template parameters of some models of the main concepts: The following classes are models of domain concepts and their associated classes: -- `CGAL::Implicit_mesh_domain_3` - `CGAL::Labeled_mesh_domain_3` - `CGAL::Polyhedral_mesh_domain_3` - `CGAL::Polyhedral_mesh_domain_with_features_3` - `CGAL::Polyhedral_complex_mesh_domain_3` -- `CGAL::Labeled_image_mesh_domain_3` -- `CGAL::Gray_image_mesh_domain_3` - `CGAL::Mesh_domain_with_polyline_features_3` - `CGAL::Mesh_polyhedron_3` - `CGAL::Triangle_accessor_3,K>` - `CGAL::Implicit_multi_domain_to_labeling_function_wrapper` +- `CGAL::Implicit_mesh_domain_3` (deprecated) +- `CGAL::Labeled_image_mesh_domain_3` (deprecated) +- `CGAL::Gray_image_mesh_domain_3` (deprecated) ## Function Templates ## diff --git a/Mesh_3/examples/Mesh_3/CMakeLists.txt b/Mesh_3/examples/Mesh_3/CMakeLists.txt index 30762fed754..480956dbaf0 100644 --- a/Mesh_3/examples/Mesh_3/CMakeLists.txt +++ b/Mesh_3/examples/Mesh_3/CMakeLists.txt @@ -81,6 +81,7 @@ if ( CGAL_FOUND ) endif() create_single_source_cgal_program( "mesh_3D_gray_image.cpp" ) + create_single_source_cgal_program( "mesh_3D_gray_image_multiple_values.cpp" ) create_single_source_cgal_program( "mesh_3D_image_with_features.cpp" ) if( CGAL_ImageIO_USE_ZLIB ) create_single_source_cgal_program( "mesh_optimization_example.cpp" ) diff --git a/Mesh_3/examples/Mesh_3/implicit_functions.h b/Mesh_3/examples/Mesh_3/implicit_functions.h index debbd838480..f5293a87028 100644 --- a/Mesh_3/examples/Mesh_3/implicit_functions.h +++ b/Mesh_3/examples/Mesh_3/implicit_functions.h @@ -25,7 +25,7 @@ double sphere_function (double x, double y, double z) // (c=(0,0,0), r=Sq_radius template -class FT_to_point_function_wrapper : public CGAL::unary_function +class FT_to_point_function_wrapper : public CGAL::cpp98::unary_function { typedef FT (*Implicit_function)(FT, FT, FT); Implicit_function function; diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image.cpp index d9cce646941..222fe1cf4c3 100644 --- a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include #include @@ -14,8 +14,7 @@ typedef float Image_word_type; // Domain typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Gray_image_mesh_domain_3 Mesh_domain; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; // Triangulation typedef CGAL::Mesh_triangulation_3::type Tr; @@ -36,8 +35,10 @@ int main(int argc, char*argv[]) std::cerr << "Error: Cannot read file " << fname << std::endl; return EXIT_FAILURE; } - // Domain - Mesh_domain domain(image, 2.9f, 0.f); + /// [Domain creation] + Mesh_domain domain = + Mesh_domain::create_gray_image_mesh_domain(image, 2.9f, 0.f); + /// [Domain creation] // Mesh criteria Mesh_criteria criteria(facet_angle=30, facet_size=6, facet_distance=2, diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_multiple_values.cmd b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_multiple_values.cmd new file mode 100644 index 00000000000..d70c103fded --- /dev/null +++ b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_multiple_values.cmd @@ -0,0 +1 @@ +data/skull_2.9.inr 1.5 2.9 3.5 diff --git a/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_multiple_values.cpp b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_multiple_values.cpp new file mode 100644 index 00000000000..bb476fea566 --- /dev/null +++ b/Mesh_3/examples/Mesh_3/mesh_3D_gray_image_multiple_values.cpp @@ -0,0 +1,85 @@ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +typedef float Image_word_type; + +// Domain +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; + +// Triangulation +typedef CGAL::Mesh_triangulation_3::type Tr; +typedef CGAL::Mesh_complex_3_in_triangulation_3