diff --git a/.travis.yml b/.travis.yml index c176918d6d2..3761737a3d6 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 . $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..af24f4e13e1 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 ] ||\ 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..7deb9f4b73c 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 . $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/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d_1.h b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d_1.h index 905b6d8eba2..c60e509abea 100644 --- a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d_1.h +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d_1.h @@ -201,7 +201,9 @@ public: }; // class Algebraic_real_traits - + + struct Construct_algebraic_real_1; + // Functors of Algebraic_kernel_d_1 struct Solve_1 { public: 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/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/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/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..2472d30f220 100644 --- a/BGL/include/CGAL/boost/graph/Euler_operations.h +++ b/BGL/include/CGAL/boost/graph/Euler_operations.h @@ -1178,7 +1178,7 @@ 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 ; } 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..bec7a54b8fd 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 @@ -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..5e2c03e95e9 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 diff --git a/Mesh_3/include/CGAL/Mesh_3/global_parameters.h b/BGL/include/CGAL/boost/parameter.h similarity index 61% rename from Mesh_3/include/CGAL/Mesh_3/global_parameters.h rename to BGL/include/CGAL/boost/parameter.h index bde73012406..1c5c1b8e979 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) @@ -39,14 +31,34 @@ #else # define BOOST_PARAMETER_MAX_ARITY 12 #endif - #include +#include -namespace CGAL { +#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 -namespace parameters { +#define CGAL_IGNORE_BOOST_PARAMETER_NAME_WARNINGS \ + CGAL_IGNORE_UNUSED_VARIABLES \ + CGAL_IGNORE_UNUSED_INTERNAL_DECLARATION + +namespace CGAL +{ +namespace parameters +{ + template struct Base { @@ -56,33 +68,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_) @@ -97,12 +115,8 @@ BOOST_PARAMETER_NAME( (maximal_number_of_vertices, tag ) maximal_number_of_verti BOOST_PARAMETER_NAME( (pointer_to_error_code, tag ) pointer_to_error_code_) 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/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/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_Euler_operations.cpp b/BGL/test/BGL/test_Euler_operations.cpp index 616ea782b3f..cdf53ec5f4c 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 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_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/CGAL_Core/include/CGAL/CORE/CoreDefs.h b/CGAL_Core/include/CGAL/CORE/CoreDefs.h index 90759e086fa..0d53c442bcc 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_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/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_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/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/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/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/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."< #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/Installation.txt b/Documentation/doc/Documentation/Installation.txt index dfb970b63f0..ac67f2cac42 100644 --- a/Documentation/doc/Documentation/Installation.txt +++ b/Documentation/doc/Documentation/Installation.txt @@ -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. 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/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/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 461ad726ad7..ae34a10d4ed 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.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.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.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/Qt/CGAL_Qt_config.h b/GraphicsView/include/CGAL/Qt/CGAL_Qt_config.h index 7ae76e3bb3a..440568e9198 100644 --- a/GraphicsView/include/CGAL/Qt/CGAL_Qt_config.h +++ b/GraphicsView/include/CGAL/Qt/CGAL_Qt_config.h @@ -13,7 +13,7 @@ // // $URL$ // $Id$ -// SPDX-License-Identifier: LGPL-3.0+ +// SPDX-License-Identifier: LGPL-3.0 // // // Author(s) : Laurent Rineau diff --git a/GraphicsView/include/CGAL/Qt/CreateOpenGLContext.h b/GraphicsView/include/CGAL/Qt/CreateOpenGLContext.h index f70d416e7a9..e5217804b01 100644 --- a/GraphicsView/include/CGAL/Qt/CreateOpenGLContext.h +++ b/GraphicsView/include/CGAL/Qt/CreateOpenGLContext.h @@ -14,7 +14,7 @@ // // $URL$ // $Id$ -// SPDX-License-Identifier: LGPL-3.0+ +// SPDX-License-Identifier: LGPL-3.0 // // // Author(s) : Laurent Rineau and Maxime Gimeno diff --git a/GraphicsView/include/CGAL/Qt/GraphicsItem.h b/GraphicsView/include/CGAL/Qt/GraphicsItem.h index 0555dc464bf..7c24add2bef 100644 --- a/GraphicsView/include/CGAL/Qt/GraphicsItem.h +++ b/GraphicsView/include/CGAL/Qt/GraphicsItem.h @@ -43,6 +43,9 @@ namespace Qt { class CGAL_QT_EXPORT GraphicsItem : public QObject, public QGraphicsItem { Q_OBJECT +#ifdef CGAL_HEADER_ONLY + Q_INTERFACES(QGraphicsItem) +#endif public Q_SLOTS: diff --git a/GraphicsView/include/CGAL/Qt/camera.h b/GraphicsView/include/CGAL/Qt/camera.h new file mode 100644 index 00000000000..44be02c980a --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/camera.h @@ -0,0 +1,543 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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..eb5e939c774 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/camera_impl.h @@ -0,0 +1,2542 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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 + +using namespace std; +using namespace CGAL::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]; + //Projection transform, the final row of projection matrix is always [0 0 -1 0] + //so we optimize for that. + 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]=-fTempo[2]; + //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,y,z; + 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,y,z; + 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); + float E = -(f+n)/(f-n); + float 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); + float E = -(f+n)/(f-n); + float 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; +} + diff --git a/GraphicsView/include/CGAL/Qt/constraint.h b/GraphicsView/include/CGAL/Qt/constraint.h new file mode 100644 index 00000000000..65beca0e189 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/constraint.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 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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..7094f0c9eb5 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/constraint_impl.h @@ -0,0 +1,303 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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 + +using namespace CGAL::qglviewer; +using namespace std; + +//////////////////////////////////////////////////////////////////////////////// +// 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; + } +} diff --git a/GraphicsView/include/CGAL/Qt/domUtils.h b/GraphicsView/include/CGAL/Qt/domUtils.h new file mode 100644 index 00000000000..61e7caa4afe --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/domUtils.h @@ -0,0 +1,195 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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..3832c14101c --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/frame.h @@ -0,0 +1,467 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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..a8433867b5a --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/frame_impl.h @@ -0,0 +1,1188 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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 + +using namespace CGAL::qglviewer; +using namespace std; + +/*! 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 = (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..d76fd993efe --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/image_interface.h @@ -0,0 +1,74 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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(i*ratio);} + } + + void imgWidthValueChanged(int i) + { + if(currentlyFocused == imgWidth + && ratioCheckBox->isChecked()) + {imgHeight->setValue(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..2fc38c84873 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/keyFrameInterpolator.h @@ -0,0 +1,376 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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..6070f37164d --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/keyFrameInterpolator_impl.h @@ -0,0 +1,588 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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 + +using namespace CGAL::qglviewer; +using namespace std; + +/*! 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..93343682346 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/manipulatedCameraFrame.h @@ -0,0 +1,261 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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..cfff7d57d14 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/manipulatedCameraFrame_impl.h @@ -0,0 +1,490 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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 + +using namespace CGAL::qglviewer; +using namespace std; + +/*! 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..4821a643d1d --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/manipulatedFrame.h @@ -0,0 +1,383 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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..a31a57d6b2a --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/manipulatedFrame_impl.h @@ -0,0 +1,594 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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 + +using namespace CGAL::qglviewer; +using namespace std; + +/*! 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..e0a71aeec2e --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/mouseGrabber.h @@ -0,0 +1,298 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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..9641f62dde7 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/mouseGrabber_impl.h @@ -0,0 +1,97 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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 + +using namespace CGAL::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..c076fcbb102 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/qglviewer.h @@ -0,0 +1,1247 @@ +/**************************************************************************** + + 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. + + libQGLViewer uses dual licensing. Commercial/proprietary software must + purchase a libQGLViewer 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. + +*****************************************************************************/ +// $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(color.redF(), color.greenF(), color.blueF(), 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..2d78bd719fb --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/qglviewer_impl.h @@ -0,0 +1,4083 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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 + +using namespace std; +using namespace CGAL::qglviewer; + +// 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 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); + 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 + float color[4]; + color[0] = foregroundColor().red() / 255.0f; + color[1] = foregroundColor().green() / 255.0f; + color[2] = 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_); + + // Restore GL state + glPopAttrib(); + glPopMatrix(); +} + +/*! 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(DRAW_AXIS, ::Qt::Key_A); + setShortcut(DRAW_GRID, ::Qt::Key_G); + setShortcut(DISPLAY_FPS, ::Qt::Key_F); + setShortcut(ENABLE_TEXT, ::Qt::SHIFT + ::Qt::Key_Question); + setShortcut(EXIT_VIEWER, ::Qt::Key_Escape); + setShortcut(CAMERA_MODE, ::Qt::Key_Space); + setShortcut(FULL_SCREEN, ::Qt::ALT + ::Qt::Key_Return); + setShortcut(STEREO, ::Qt::Key_S); + setShortcut(ANIMATION, ::Qt::Key_Return); + setShortcut(HELP, ::Qt::Key_H); + setShortcut(EDIT_CAMERA, ::Qt::Key_C); + setShortcut(MOVE_CAMERA_LEFT, ::Qt::Key_Left); + setShortcut(MOVE_CAMERA_RIGHT, ::Qt::Key_Right); + setShortcut(MOVE_CAMERA_UP, ::Qt::Key_Up); + setShortcut(MOVE_CAMERA_DOWN, ::Qt::Key_Down); + setShortcut(INCREASE_FLYSPEED, ::Qt::Key_Plus); + setShortcut(DECREASE_FLYSPEED, ::Qt::Key_Minus); + + keyboardActionDescription_[DISPLAY_FPS] = + tr("Toggles the display of the FPS", "DISPLAY_FPS action description"); + keyboardActionDescription_[FULL_SCREEN] = + tr("Toggles full screen display", "FULL_SCREEN action description"); + keyboardActionDescription_[DRAW_AXIS] = tr( + "Toggles the display of the world axis", "DRAW_AXIS action description"); + keyboardActionDescription_[DRAW_GRID] = + tr("Toggles the display of the XY grid", "DRAW_GRID action description"); + keyboardActionDescription_[CAMERA_MODE] = tr( + "Changes camera mode (observe or fly)", "CAMERA_MODE action description"); + keyboardActionDescription_[STEREO] = + tr("Toggles stereo display", "STEREO action description"); + keyboardActionDescription_[HELP] = + tr("Opens this help window", "HELP action description"); + keyboardActionDescription_[ANIMATION] = + tr("Starts/stops the animation", "ANIMATION action description"); + keyboardActionDescription_[EDIT_CAMERA] = + tr("Toggles camera paths display", + "EDIT_CAMERA action description"); // TODO change + keyboardActionDescription_[ENABLE_TEXT] = + tr("Toggles the display of the text", "ENABLE_TEXT action description"); + keyboardActionDescription_[EXIT_VIEWER] = + tr("Exits program", "EXIT_VIEWER action description"); + keyboardActionDescription_[MOVE_CAMERA_LEFT] = + tr("Moves camera left", "MOVE_CAMERA_LEFT action description"); + keyboardActionDescription_[MOVE_CAMERA_RIGHT] = + tr("Moves camera right", "MOVE_CAMERA_RIGHT action description"); + keyboardActionDescription_[MOVE_CAMERA_UP] = + tr("Moves camera up", "MOVE_CAMERA_UP action description"); + keyboardActionDescription_[MOVE_CAMERA_DOWN] = + tr("Moves camera down", "MOVE_CAMERA_DOWN action description"); + keyboardActionDescription_[INCREASE_FLYSPEED] = + tr("Increases fly speed", "INCREASE_FLYSPEED action description"); + keyboardActionDescription_[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) { + MouseHandler mh = (MouseHandler)(handler); + ::Qt::KeyboardModifiers modifiers = + (mh == FRAME) ? frameKeyboardModifiers : cameraKeyboardModifiers; + + setMouseBinding(modifiers, ::Qt::LeftButton, mh, ROTATE); + setMouseBinding(modifiers, ::Qt::MidButton, mh, ZOOM); + setMouseBinding(modifiers, ::Qt::RightButton, mh, TRANSLATE); + + setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, mh, SCREEN_ROTATE); + + setWheelBinding(modifiers, mh, ZOOM); + } + + // Z o o m o n r e g i o n + setMouseBinding(::Qt::ShiftModifier, ::Qt::MidButton, CAMERA, ZOOM_ON_REGION); + + // S e l e c t + setMouseBinding(::Qt::ShiftModifier, ::Qt::LeftButton, SELECT); + + setMouseBinding(::Qt::ShiftModifier, ::Qt::RightButton, RAP_FROM_PIXEL); + // D o u b l e c l i c k + setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, ALIGN_CAMERA, true); + setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, SHOW_ENTIRE_SCENE, true); + setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, CENTER_SCENE, true); + + setMouseBinding(frameKeyboardModifiers, ::Qt::LeftButton, ALIGN_FRAME, true); + // middle double click makes no sense for manipulated frame + setMouseBinding(frameKeyboardModifiers, ::Qt::RightButton, 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, ZOOM_ON_PIXEL); + setMouseBinding(::Qt::Key_Z, ::Qt::NoModifier, ::Qt::RightButton, 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, CAMERA, TRANSLATE); + setMouseBinding(macKeyboardModifiers, ::Qt::LeftButton, CENTER_SCENE, true); + setMouseBinding(frameKeyboardModifiers | macKeyboardModifiers, ::Qt::LeftButton, + CENTER_FRAME, true); + setMouseBinding(frameKeyboardModifiers | macKeyboardModifiers, ::Qt::LeftButton, + FRAME, 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(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) { + const Vec proj = camera_->projectedCoordinatesOf(Vec(x, y, z)); + renderText(proj.x, 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(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 NO_CLICK_ACTION: + break; + case ZOOM_ON_PIXEL: + camera()->interpolateToZoomOnPixel(e->pos()); + break; + case ZOOM_TO_FIT: + camera()->interpolateToFitScene(); + break; + case SELECT: + select(e); + update(); + break; + case RAP_FROM_PIXEL: + if (!camera()->setPivotPointFromPixel(e->pos())) + camera()->setPivotPoint(sceneCenter()); + setVisualHintsMask(1); + update(); + break; + case RAP_IS_CENTER: + camera()->setPivotPoint(sceneCenter()); + setVisualHintsMask(1); + update(); + break; + case CENTER_FRAME: + if (manipulatedFrame()) + manipulatedFrame()->projectOnLine(camera()->position(), + camera()->viewDirection()); + break; + case CENTER_SCENE: + camera()->centerScene(); + break; + case SHOW_ENTIRE_SCENE: + camera()->showEntireScene(); + break; + case ALIGN_FRAME: + if (manipulatedFrame()) + manipulatedFrame()->alignWithFrame(camera()->frame()); + break; + case ALIGN_CAMERA: + Frame *frame = new 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 == FRAME) && (it.key().button == e->button())) { + ManipulatedFrame *mf = + dynamic_cast(mouseGrabber()); + if (mouseGrabberIsAManipulatedCameraFrame_) { + mf->ManipulatedFrame::startAction(it.value().action, + it.value().withConstraint); + mf->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 CAMERA: + camera()->frame()->startAction(map.action, map.withConstraint); + camera()->frame()->mousePressEvent(e, camera()); + break; + case 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 == 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())) + ->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_ == 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 (MouseGrabber *mg, 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())) + ->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 == FRAME) { + ManipulatedFrame *mf = + dynamic_cast(mouseGrabber()); + if (mouseGrabberIsAManipulatedCameraFrame_) { + mf->ManipulatedFrame::startAction(it.value().action, + it.value().withConstraint); + mf->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 CAMERA: + camera()->frame()->startAction(map.action, map.withConstraint); + camera()->frame()->wheelEvent(e, camera()); + break; + case 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(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(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 += " Mesh_criteria; 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..401d307dd31 100644 --- a/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h +++ b/Mesh_3/include/CGAL/Implicit_to_labeling_function_wrapper.h @@ -111,7 +111,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 @@ -121,18 +127,13 @@ public: /// Operator () return_type operator()(const Point_3& p, const bool = true) 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) ); 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_criteria_3.h b/Mesh_3/include/CGAL/Mesh_criteria_3.h index 2360fb78a3c..ecb5ead9ffb 100644 --- a/Mesh_3/include/CGAL/Mesh_criteria_3.h +++ b/Mesh_3/include/CGAL/Mesh_criteria_3.h @@ -33,7 +33,7 @@ #include #include -#include +#include #include #include #include @@ -45,8 +45,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..312d17274d1 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 @@ -623,6 +623,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 +830,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,17 +864,14 @@ 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 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(); @@ -1013,6 +1031,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 +1159,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 +1242,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 +1258,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 +1272,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 +1399,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 +1422,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..52e5996cde2 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 diff --git a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h index 0650b628eef..755835811a3 100644 --- a/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h +++ b/Mesh_3/include/CGAL/Polyhedral_mesh_domain_3.h @@ -32,7 +32,7 @@ #include -#include +#include #include #include 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..2240b0f1080 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; diff --git a/Mesh_3/include/CGAL/exude_mesh_3.h b/Mesh_3/include/CGAL/exude_mesh_3.h index ba74aa72111..04dad363b92 100644 --- a/Mesh_3/include/CGAL/exude_mesh_3.h +++ b/Mesh_3/include/CGAL/exude_mesh_3.h @@ -34,8 +34,7 @@ #include #include #include -#include -#include +#include namespace CGAL { @@ -46,8 +45,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/helpers.h b/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h new file mode 100644 index 00000000000..6baa4ed6dd8 --- /dev/null +++ b/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h @@ -0,0 +1,195 @@ +// 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 +{ + 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 + +} // end CGAL + +#include + +#endif // CGAL_MESH_3_INTERNAL_MESH_3_HELPERS_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..3f2a3c051d8 100644 --- a/Mesh_3/include/CGAL/lloyd_optimize_mesh_3.h +++ b/Mesh_3/include/CGAL/lloyd_optimize_mesh_3.h @@ -30,7 +30,7 @@ #include -#include +#include #include #include #include @@ -47,8 +47,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..8d31b78da54 100644 --- a/Mesh_3/include/CGAL/make_mesh_3.h +++ b/Mesh_3/include/CGAL/make_mesh_3.h @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include #include @@ -123,8 +123,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 +404,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..7627ab07510 100644 --- a/Mesh_3/include/CGAL/odt_optimize_mesh_3.h +++ b/Mesh_3/include/CGAL/odt_optimize_mesh_3.h @@ -30,7 +30,7 @@ #include -#include +#include #include #include #include @@ -47,8 +47,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..74c68e397c5 100644 --- a/Mesh_3/include/CGAL/perturb_mesh_3.h +++ b/Mesh_3/include/CGAL/perturb_mesh_3.h @@ -30,7 +30,7 @@ #include -#include +#include #include #include #include @@ -48,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/refine_mesh_3.h b/Mesh_3/include/CGAL/refine_mesh_3.h index fb3e4aee3d4..21547fc6ca6 100644 --- a/Mesh_3/include/CGAL/refine_mesh_3.h +++ b/Mesh_3/include/CGAL/refine_mesh_3.h @@ -31,9 +31,9 @@ #include #include +#include #include #include -#include #include #include #include @@ -236,8 +236,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 +412,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 +445,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/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_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_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 index 3a45601d56c..9293e47a8c0 100644 --- 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 @@ -1,4 +1,4 @@ -#define CGAL_NO_DEPRECATION_WARNINGS 1 +#include #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 index 48cb3d4ae37..6d51adfc953 100644 --- 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 @@ -23,7 +23,7 @@ // File Description : //****************************************************************************** -#define CGAL_NO_DEPRECATION_WARNINGS 1 +#include #include "test_meshing_utilities.h" #include diff --git a/Mesh_3/test/Mesh_3/test_mesh_implicit_domains.cpp b/Mesh_3/test/Mesh_3/test_mesh_implicit_domains.cpp index f302231e0d4..921a6bbea04 100644 --- a/Mesh_3/test/Mesh_3/test_mesh_implicit_domains.cpp +++ b/Mesh_3/test/Mesh_3/test_mesh_implicit_domains.cpp @@ -6,9 +6,6 @@ // subdomain. //****************************************************************************** - -#define CGAL_NO_DEPRECATION_WARNINGS 1 - #include "debug.h" #include @@ -16,8 +13,8 @@ #include #include -#include -#include +#include +#include #include #include "implicit_functions.h" @@ -30,12 +27,12 @@ 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; + typedef CGAL::Exact_predicates_inexact_constructions_kernel K; + typedef FT_to_point_function_wrapper Function; + typedef CGAL::Implicit_vector_to_labeling_function_wrapper + Function_wrapper; + typedef Function_wrapper::Function_vector Function_vector; + typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; // Triangulation typedef typename CGAL::Mesh_triangulation_3< 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..26e7093cb91 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,4 +1,4 @@ -#define CGAL_NO_DEPRECATION_WARNINGS +#include #include 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_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)<<"] "< class Real_embeddable_traits< Gmpq > 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/mpq_class.h b/Number_types/include/CGAL/mpq_class.h index 8d739ce2c5c..d143bdf6a36 100644 --- a/Number_types/include/CGAL/mpq_class.h +++ b/Number_types/include/CGAL/mpq_class.h @@ -209,9 +209,14 @@ class Real_embeddable_traits< mpq_class > 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/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/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_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/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/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/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/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/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..97a400388ce 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 @@ -1021,7 +1021,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) @@ -1055,7 +1055,7 @@ 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(mesh_)); + CGAL_assertion(is_valid_polygon_mesh(mesh_)); CGAL_assertion(is_triangle_mesh(mesh_)); #ifdef CGAL_PMP_REMESHING_DEBUG debug_self_intersections(); 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..7fa9845c48b 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); @@ -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; 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/repair.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h index b44a11839e8..46a46db6e3b 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) ); } } @@ -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/transform.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/transform.h new file mode 100644 index 00000000000..bf11b1a4856 --- /dev/null +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/transform.h @@ -0,0 +1,68 @@ +// 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` should 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))); + } +} +} +} + +#endif 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_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..639242b908b 100644 --- a/Polyhedron/demo/Polyhedron/C3t3_type.h +++ b/Polyhedron/demo/Polyhedron/C3t3_type.h @@ -3,7 +3,7 @@ // 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" 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..5344f2e6c8d 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() 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/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/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..cdb8af83737 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Io_image_plugin.cpp @@ -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,14 +153,10 @@ 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; @@ -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; @@ -682,7 +678,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 +751,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_function.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h index 2ce3be3db6d..d5529cf1054 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_function.h @@ -361,7 +361,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/Volume_plane.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane.h index b5c5ada6b78..4824641ed7d 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; @@ -63,7 +64,7 @@ public: 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 *); @@ -115,7 +116,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 +138,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 +267,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 +295,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_ ; } @@ -380,9 +381,9 @@ const char* Volume_plane::fragmentShader_bordures_source = template Volume_plane::Volume_plane() - : Volume_plane_interface(new qglviewer::ManipulatedFrame) + : Volume_plane_interface(new CGAL::qglviewer::ManipulatedFrame) { - 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); @@ -621,7 +622,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 +631,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], c_spheres[i*3+1], c_spheres[i*3+2]); if( (center.x - pos.x) * (center.x - pos.x) + (center.y - pos.y) * (center.y - pos.y) + @@ -660,8 +661,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 +671,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..17556dea369 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_intersection.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Volume_plane_intersection.cpp @@ -48,7 +48,7 @@ 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); 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..baf72b36513 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 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..891d6d7e7e0 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()*M_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()*M_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/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/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/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..cca1c9db01f 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,17 @@ 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; poly_item->select(orig.x, orig.y, orig.z, dir.x, dir.y, dir.z); } viewer->doneCurrent(); @@ -221,10 +217,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 +230,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); @@ -290,9 +286,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, @@ -322,11 +318,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 +338,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 +356,19 @@ 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; + const CGAL::qglviewer::Vec& orig = camera->position() - offset; + const CGAL::qglviewer::Vec& dir = point - orig; is_highlighting = true; poly_item->select(orig.x, orig.y, orig.z, dir.x, dir.y, dir.z); is_highlighting = false; @@ -548,7 +544,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 +563,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 +574,7 @@ protected: { if(target == mainwindow) { - QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); + CGAL::QGLViewer* viewer = *CGAL::QGLViewer::QGLViewerPool().begin(); viewer->setFocus(); return false; } @@ -625,7 +617,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 +628,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) @@ -665,7 +660,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/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/Point_set_selection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_selection_plugin.cpp index 60fafc6116f..ac2c608ad35 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,8 +245,8 @@ 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 ()); + CGAL::qglviewer::Vec vsp = camera->projectedCoordinatesOf (vp + offset); bool now_selected = false; if(!ui_widget.box->isChecked()) now_selected = visualizer->is_selected (vsp); @@ -619,7 +619,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 +650,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 +665,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 +691,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 +729,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 +746,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 +760,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 +785,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 +997,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/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..63d178be327 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" @@ -176,16 +176,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 +204,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 +245,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 +253,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 +323,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/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..d6f2c820ae0 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; @@ -847,11 +847,11 @@ Scene_c3t3_item_priv::compute_color_map(const QColor& c) } } -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 +1074,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 +1109,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 +1140,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); @@ -1479,7 +1479,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,7 +1540,7 @@ 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); @@ -1654,7 +1654,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 +1672,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 +1774,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 +1795,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()); @@ -2072,7 +2072,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..7cece92507f 100644 --- a/Polyhedron/demo/Polyhedron/Scene_image_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_image_item.cpp @@ -320,7 +320,7 @@ 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(); + const CGAL::qglviewer::Vec offset = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); indices_.insert(std::make_pair(compute_position(i,j,k), vertices_.size()/3)); //resize the "border vertices" @@ -423,7 +423,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(); @@ -845,7 +845,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..a11c68658e8 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; i(*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..cb7e5ba4d93 100644 --- a/Polyhedron/demo/Polyhedron/Scene_plane_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_plane_item.cpp @@ -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..e375a6ce04a 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -348,7 +348,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..e9b878e1c93 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,7 +473,7 @@ 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()) @@ -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..c89b80cd686 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp @@ -452,7 +452,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 +578,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 +833,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 +1105,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 +1828,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 +1931,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 +1962,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 +1978,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 +2166,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 +2184,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; 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..d9dce50d31f 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; @@ -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(); diff --git a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp index 9dcf97dbe84..d3de2a71771 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))); @@ -872,7 +872,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 +1554,14 @@ 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); + CGAL::qglviewer::Vec dir = point_under - viewer->camera()->position(); 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 +1632,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 +1642,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 +1738,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 +1746,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 +1807,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 +1836,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 +1855,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 +1874,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 +1895,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 +1916,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 +1930,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..62de73bbbb9 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,7 +19,7 @@ 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()) @@ -43,7 +43,7 @@ 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)) diff --git a/Polyhedron/demo/Polyhedron/Viewer.cpp b/Polyhedron/demo/Polyhedron/Viewer.cpp index f4a42bf5259..acbf788d131 100644 --- a/Polyhedron/demo/Polyhedron/Viewer.cpp +++ b/Polyhedron/demo/Polyhedron/Viewer.cpp @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include @@ -30,49 +29,23 @@ 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; - }; - //! 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 +56,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 +76,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 +86,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 +104,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 +123,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 +187,17 @@ 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->_recentFunctions->initializeOpenGLFunctions(); } glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDARBPROC)this->context()->getProcAddress("glDrawArraysInstancedARB"); if(!glDrawArraysInstanced) @@ -321,100 +219,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 +272,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 +309,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 +326,7 @@ void Viewer::contextMenuEvent(QContextMenuEvent* event) event->accept(); } else { - QGLViewer::contextMenuEvent(event); + CGAL::QGLViewer::contextMenuEvent(event); } } @@ -577,14 +352,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 +390,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 +415,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 +476,7 @@ bool Viewer::inDrawWithNames() const { void Viewer::drawWithNames() { - QGLViewer::draw(); + CGAL::QGLViewer::draw(); d->draw_aux(true, this); } @@ -717,18 +484,18 @@ 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; + const CGAL::qglviewer::Vec orig = camera()->position() - offset(); + const CGAL::qglviewer::Vec 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 +514,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 +524,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 +539,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 +573,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 +654,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,92 +687,22 @@ 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); @@ -1254,16 +712,11 @@ void Viewer::drawVisualHints() 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 +819,7 @@ void Viewer::wheelEvent(QWheelEvent* e) update(); } else - QGLViewer::wheelEvent(e); + CGAL::QGLViewer::wheelEvent(e); } bool Viewer::testDisplayId(double x, double y, double z) @@ -1399,12 +852,10 @@ void Viewer::paintGL() 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 +865,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 +889,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) { @@ -1482,35 +910,35 @@ void Viewer_impl::showDistance(QPoint pixel) v[0] = APoint.x; v[1] = APoint.y; v[2] = APoint.z; v[3] = BPoint.x; v[4] = BPoint.y; v[5] = 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(APoint.x, APoint.y, 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(BPoint.x, BPoint.y, 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); + CGAL::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); 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 +955,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 +980,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 +1017,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 +1025,3 @@ void Viewer::setStaticImage(QImage image) { d->static_image = image; } const QImage& Viewer:: staticImage() const { return d->static_image; } - - -#include "Viewer.moc" diff --git a/Polyhedron/demo/Polyhedron/Viewer.h b/Polyhedron/demo/Polyhedron/Viewer.h index e104622dc1d..b36ed537775 100644 --- a/Polyhedron/demo/Polyhedron/Viewer.h +++ b/Polyhedron/demo/Polyhedron/Viewer.h @@ -9,8 +9,6 @@ #include #include #include - -#include #include #include #include @@ -38,7 +36,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 +45,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 +74,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 +109,15 @@ 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); } protected: - void postDraw()Q_DECL_OVERRIDE; void paintEvent(QPaintEvent *)Q_DECL_OVERRIDE; void paintGL()Q_DECL_OVERRIDE; @@ -146,15 +132,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/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..a28bb940214 100644 --- a/Polyhedron/demo/Polyhedron/include/id_printing.h +++ b/Polyhedron/demo/Polyhedron/include/id_printing.h @@ -116,11 +116,11 @@ 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(); + CGAL::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); @@ -169,7 +169,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, @@ -390,7 +390,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); @@ -425,7 +425,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); @@ -458,7 +458,7 @@ 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)) @@ -518,7 +518,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 +599,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/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..bf1104c3c3b 100644 --- a/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv.cpp +++ b/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include #include diff --git a/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv_with_boundary.cpp b/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv_with_boundary.cpp index 90ead40b2ff..744440fd123 100644 --- a/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv_with_boundary.cpp +++ b/Polyhedron/examples/Polyhedron/polyhedron_prog_subdiv_with_boundary.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include #include diff --git a/Polyhedron/examples/Polyhedron/polyhedron_self_intersection.cpp b/Polyhedron/examples/Polyhedron/polyhedron_self_intersection.cpp index 5bea593eaa1..a70ee0fd0e2 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 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/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_traits_d.h b/Polynomial/include/CGAL/Polynomial_traits_d.h index 42c96b05c15..1c8b7f827af 100644 --- a/Polynomial/include/CGAL/Polynomial_traits_d.h +++ b/Polynomial/include/CGAL/Polynomial_traits_d.h @@ -729,7 +729,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; @@ -1537,10 +1539,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/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 fba1c0d6573..d025f3962e2 100644 --- a/Property_map/include/CGAL/property_map.h +++ b/Property_map/include/CGAL/property_map.h @@ -418,6 +418,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]); } @@ -443,20 +446,29 @@ 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 diff --git a/Property_map/test/Property_map/CMakeLists.txt b/Property_map/test/Property_map/CMakeLists.txt index 8e294e8dbae..cf2d22c7469 100644 --- a/Property_map/test/Property_map/CMakeLists.txt +++ b/Property_map/test/Property_map/CMakeLists.txt @@ -49,6 +49,8 @@ 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" ) 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/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/include/CGAL/internal/boost/array_binary_tree.hpp b/STL_Extension/include/CGAL/internal/boost/array_binary_tree.hpp index ed646779099..bdc1eeb1a1a 100644 --- a/STL_Extension/include/CGAL/internal/boost/array_binary_tree.hpp +++ b/STL_Extension/include/CGAL/internal/boost/array_binary_tree.hpp @@ -20,7 +20,7 @@ #ifndef CGAL_INTERNAL_ARRAY_BINARY_TREE_HPP #define CGAL_INTERNAL_ARRAY_BINARY_TREE_HPP -#include +#include #include #include @@ -52,12 +52,12 @@ public: struct children_type { struct iterator - : ::boost::iterator { // replace with iterator_adaptor implementation -JGS + typedef std::forward_iterator_tag iterator_category; + typedef ArrayBinaryTreeNode value_type; + typedef size_type difference_type; + typedef ArrayBinaryTreeNode* pointer; + typedef ArrayBinaryTreeNode& reference; inline iterator() : i(0), n(0) { } inline iterator(const iterator& x) : r(x.r), i(x.i), n(x.n), id(x.id) { } 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_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/Scripts/developer_scripts/cgal_check_dependencies.sh b/Scripts/developer_scripts/cgal_check_dependencies.sh index d394e40f56d..f05b8e064ce 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 @@ -29,7 +29,7 @@ do done cmake -DCGAL_HEADER_ONLY=FALSE -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 +make -j$(nproc --all) -k packages_dependencies echo " Checks finished" for pkg_path in $CGAL_ROOT/* do @@ -37,13 +37,11 @@ do if [ -f "$pkg_path/package_info/$pkg/dependencies" ]; then 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 are new and not committed." + 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 - HAS_DIFF=TRUE - echo "Differences in $pkg: $PKG_DIFF have disappeared." + 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 @@ -53,7 +51,8 @@ done echo " Checks finished" cd $CGAL_ROOT rm -r dep_check_build -if [ -n "$HAS_DIFF" ]; then +if [ -n "$TOTAL_RES" ]; then + echo "$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 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/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/test/Spatial_searching/Point_with_info.h b/Spatial_searching/test/Spatial_searching/Point_with_info.h index 48557ff6cdd..806a9d917ea 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];} }; 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/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_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..5f0d705bcf3 100644 --- a/Surface_mesher/demo/Surface_mesher/volume.cpp +++ b/Surface_mesher/demo/Surface_mesher/volume.cpp @@ -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())); 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..f57c6df8943 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 @@ -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/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/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_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/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..d3f440ad362 100644 --- a/Triangulation_3/include/CGAL/Regular_triangulation_3.h +++ b/Triangulation_3/include/CGAL/Regular_triangulation_3.h @@ -827,10 +827,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 +2429,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/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_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
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 CAMERA: + text += " " + tr("camera", "Suffix after action"); + break; + case 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 CAMERA: + text += " " + tr("camera", "Suffix after action"); + break; + case 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() != INCREASE_FLYSPEED) && (it.key() != 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_) { + 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(KeyboardAction id) { + switch (id) { + case DRAW_AXIS: + toggleAxisIsDrawn(); + break; + case DRAW_GRID: + toggleGridIsDrawn(); + break; + case DISPLAY_FPS: + toggleFPSIsDisplayed(); + break; + case ENABLE_TEXT: + toggleTextIsEnabled(); + break; + case EXIT_VIEWER: + saveStateToFileForAllViewers(); + qApp->closeAllWindows(); + break; + case FULL_SCREEN: + toggleFullScreen(); + break; + case STEREO: + toggleStereoDisplay(); + break; + case ANIMATION: + toggleAnimation(); + break; + case HELP: + help(); + break; + case EDIT_CAMERA: + toggleCameraIsEdited(); + break; + case CAMERA_MODE: + toggleCameraMode(); + displayMessage(cameraIsInRotateMode() + ? tr("Camera in observer mode", "Feedback message") + : tr("Camera in fly mode", "Feedback message")); + break; + + case MOVE_CAMERA_LEFT: + camera()->frame()->translate(camera()->frame()->inverseTransformOf( + Vec(-10.0 * camera()->flySpeed(), 0.0, 0.0))); + update(); + break; + case MOVE_CAMERA_RIGHT: + camera()->frame()->translate(camera()->frame()->inverseTransformOf( + Vec(10.0 * camera()->flySpeed(), 0.0, 0.0))); + update(); + break; + case MOVE_CAMERA_UP: + camera()->frame()->translate(camera()->frame()->inverseTransformOf( + Vec(0.0, 10.0 * camera()->flySpeed(), 0.0))); + update(); + break; + case MOVE_CAMERA_DOWN: + camera()->frame()->translate(camera()->frame()->inverseTransformOf( + Vec(0.0, -10.0 * camera()->flySpeed(), 0.0))); + update(); + break; + + case INCREASE_FLYSPEED: + camera()->setFlySpeed(camera()->flySpeed() * 1.5); + break; + case 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(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(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, MouseHandler handler, + 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, MouseHandler handler, + MouseAction action, bool withConstraint) { + if ((handler == FRAME) && + ((action == MOVE_FORWARD) || (action == MOVE_BACKWARD) || + (action == ROLL) || (action == LOOK_AROUND) || + (action == 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 == 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, 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, 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 == 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, + MouseHandler handler, 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, + MouseHandler handler, MouseAction action, + bool withConstraint) { + //#CONNECTION# ManipulatedFrame::wheelEvent and + // ManipulatedCameraFrame::wheelEvent switches + if ((action != ZOOM) && (action != MOVE_FORWARD) && + (action != MOVE_BACKWARD) && (action != NO_MOUSE_ACTION)) { + qWarning("Cannot bind %s to wheel", + mouseActionString(action).toLatin1().constData()); + return; + } + + if ((handler == FRAME) && (action != ZOOM) && (action != 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 == 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 +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 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(MouseHandler handler, 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(-1); + 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(MouseHandler handler, 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(). +*/ +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 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 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(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(CAMERA, 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(CAMERA, ROTATE, true /*constraint*/, key, modifiers, + button); + bool rotateMode = button != ::Qt::NoButton; + + if (!rotateMode) { + getMouseActionBinding(CAMERA, MOVE_FORWARD, true /*constraint*/, key, + modifiers, button); + } + + //#CONNECTION# setDefaultMouseBindings() + if (rotateMode) { + camera()->frame()->updateSceneUpVector(); + camera()->frame()->stopSpinning(); + + setMouseBinding(modifiers, ::Qt::LeftButton, CAMERA, MOVE_FORWARD); + setMouseBinding(modifiers, ::Qt::MidButton, CAMERA, LOOK_AROUND); + setMouseBinding(modifiers, ::Qt::RightButton, CAMERA, MOVE_BACKWARD); + + setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, CAMERA, ROLL); + + setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, NO_CLICK_ACTION, true); + setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, NO_CLICK_ACTION, true); + setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, NO_CLICK_ACTION, true); + + setWheelBinding(modifiers, CAMERA, MOVE_FORWARD); + } else { + // Should stop flyTimer. But unlikely and not easy. + setMouseBinding(modifiers, ::Qt::LeftButton, CAMERA, ROTATE); + setMouseBinding(modifiers, ::Qt::MidButton, CAMERA, ZOOM); + setMouseBinding(modifiers, ::Qt::RightButton, CAMERA, TRANSLATE); + + setMouseBinding(::Qt::Key_R, modifiers, ::Qt::LeftButton, CAMERA, + SCREEN_ROTATE); + + setMouseBinding(::Qt::NoModifier, ::Qt::LeftButton, ALIGN_CAMERA, true); + setMouseBinding(::Qt::NoModifier, ::Qt::MidButton, SHOW_ENTIRE_SCENE, true); + setMouseBinding(::Qt::NoModifier, ::Qt::RightButton, CENTER_SCENE, true); + + setWheelBinding(modifiers, CAMERA, 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(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] = 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] = 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 = (pow(-1, i)*(1-i/2)); + float y = (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((camera()->projectedCoordinatesOf(camera()->pivotPoint()).x-size/2)*devicePixelRatio(), (height() - camera()->projectedCoordinatesOf(camera()->pivotPoint()).y-size/2)*devicePixelRatio(), size, size); + glScissor ((camera()->projectedCoordinatesOf(camera()->pivotPoint()).x-size/2)*devicePixelRatio(), (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) { + CGAL::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/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 = (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 + double D = 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(color.x); + data.push_back(color.y); + data.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.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(color.x); + data.push_back(color.y); + data.push_back(color.z); + //point C1 + D = (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(color.x); + data.push_back(color.y); + data.push_back(color.z); + //point A2 + D = (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 = 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(color.x); + data.push_back(color.y); + data.push_back(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 = 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.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..56b2e0be1f8 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/qglviewer_impl_list.h @@ -0,0 +1,37 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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..c5f616cd3c3 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/quaternion.h @@ -0,0 +1,344 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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..bc8960bebf1 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/quaternion_impl.h @@ -0,0 +1,561 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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 +using namespace CGAL::qglviewer; +using namespace std; + +/*! 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 +ostream &operator<<(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..33aa7e919e9 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/vec.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 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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..2c3bfa37b0f --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/vec_impl.h @@ -0,0 +1,183 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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 + +using namespace CGAL::qglviewer; +using namespace std; + +/*! 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 +ostream &operator<<(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..413d4b60213 --- /dev/null +++ b/GraphicsView/include/CGAL/Qt/viewer_actions.h @@ -0,0 +1,105 @@ +/**************************************************************************** + + Copyright (c) 2018 GeometryFactory Sarl (France). + Copyright (C) 2002-2014 Gilles Debunne. All rights reserved. + + This file is part of a fork 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 + version 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + + 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. + +*****************************************************************************/ +// $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/Installation/CHANGES.md b/Installation/CHANGES.md index e81d5b207f3..e98bae049d5 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -6,6 +6,10 @@ Release 4.13 Release date: September 2018 +### 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 @@ -33,6 +37,9 @@ 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()` Release 4.12 ------------ @@ -208,7 +215,10 @@ 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::is_valid_polygon_mesh` that checks the + validity of a polygon mesh using BGL functions. + +- 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..728e16f2ec5 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) @@ -890,7 +889,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 +1059,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 +1069,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 +1122,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 +1139,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 +1156,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 +1240,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 +1262,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 +1270,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 +1290,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 +1327,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/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/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/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/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/Concepts/FunctionObjectConcepts.h b/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h index 2cb3db219c7..ef058713356 100644 --- a/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h +++ b/Kernel_23/doc/Kernel_23/Concepts/FunctionObjectConcepts.h @@ -5976,6 +5976,12 @@ 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`. 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/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/demo/Linear_cell_complex/CMakeLists.txt b/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt index 40b748a36ca..cf875857d47 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 @@ -73,8 +69,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..d1831d39149 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp +++ b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp @@ -1006,9 +1006,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/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/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/lloyd_optimize_mesh_2.h b/Mesh_2/include/CGAL/lloyd_optimize_mesh_2.h index 48b1457c19f..ee2f6e42d48 100644 --- a/Mesh_2/include/CGAL/lloyd_optimize_mesh_2.h +++ b/Mesh_2/include/CGAL/lloyd_optimize_mesh_2.h @@ -31,47 +31,18 @@ #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 +52,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 +150,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/examples/Mesh_3/mesh_hybrid_mesh_domain.cpp b/Mesh_3/examples/Mesh_3/mesh_hybrid_mesh_domain.cpp index 9c5a5d1ae50..8316a6f5335 100644 --- a/Mesh_3/examples/Mesh_3/mesh_hybrid_mesh_domain.cpp +++ b/Mesh_3/examples/Mesh_3/mesh_hybrid_mesh_domain.cpp @@ -7,13 +7,11 @@ #include #include +#include #include #include #include -// IO -#include - // Ouput #include 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