diff --git a/.github/workflows/delete_doc.yml b/.github/workflows/delete_doc.yml index 1304a7895c9..d648a601e91 100644 --- a/.github/workflows/delete_doc.yml +++ b/.github/workflows/delete_doc.yml @@ -26,7 +26,7 @@ jobs: git rm -r ${PR_NUMBER} fi #git diff exits with 1 if there is a diff - if !git diff --quiet; then + if ! git diff --quiet; then git commit -a --amend -m"base commit" && git push -f -u origin master fi diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index ad59dd4d765..00000000000 --- a/.travis.yml +++ /dev/null @@ -1,79 +0,0 @@ -language: cpp -dist: bionic -sudo: required -git: - depth: 3 -env: - matrix: - - PACKAGE='CHECK' - - PACKAGE='AABB_tree Advancing_front_surface_reconstruction Algebraic_foundations ' - - PACKAGE='Algebraic_kernel_d Algebraic_kernel_for_circles Algebraic_kernel_for_spheres ' - - PACKAGE='Alpha_shapes_2 Alpha_shapes_3 Apollonius_graph_2 ' - - PACKAGE='Arithmetic_kernel Arrangement_on_surface_2 BGL ' - - PACKAGE='Barycentric_coordinates_2 Boolean_set_operations_2 Bounding_volumes ' - - PACKAGE='Box_intersection_d CGAL_Core CGAL_ImageIO ' - - PACKAGE='CGAL_ipelets Cartesian_kernel Circular_kernel_2 ' - - PACKAGE='Circular_kernel_3 Circulator Classification ' - - PACKAGE='Combinatorial_map Cone_spanners_2 Convex_decomposition_3 ' - - PACKAGE='Convex_hull_2 Convex_hull_3 Convex_hull_d ' - - PACKAGE='Distance_2 Distance_3 Envelope_2 ' - - PACKAGE='Envelope_3 Filtered_kernel Generalized_map ' - - PACKAGE='Generator Geomview GraphicsView ' - - PACKAGE='HalfedgeDS Hash_map Heat_method_3 ' - - PACKAGE='Homogeneous_kernel Hyperbolic_triangulation_2 Inscribed_areas ' - - PACKAGE='Installation Interpolation Intersections_2 ' - - PACKAGE='Intersections_3 Interval_skip_list Interval_support ' - - PACKAGE='Jet_fitting_3 Kernel_23 Kernel_d ' - - PACKAGE='LEDA Linear_cell_complex MacOSX ' - - PACKAGE='Maintenance Matrix_search Mesh_2 ' - - PACKAGE='Mesh_3 Mesher_level Minkowski_sum_2 ' - - PACKAGE='Minkowski_sum_3 Modifier Modular_arithmetic ' - - PACKAGE='Nef_2 Nef_3 Nef_S2 ' - - PACKAGE='NewKernel_d Number_types OpenNL ' - - PACKAGE='Optimal_bounding_box Optimal_transportation_reconstruction_2 Optimisation_basic ' - - PACKAGE='Partition_2 Periodic_2_triangulation_2 Periodic_3_mesh_3 ' - - PACKAGE='Periodic_3_triangulation_3 Periodic_4_hyperbolic_triangulation_2 Point_set_2 ' - - PACKAGE='Point_set_3 Point_set_processing_3 Poisson_surface_reconstruction_3 ' - - PACKAGE='Polygon Polygon_mesh_processing Polygonal_surface_reconstruction ' - - PACKAGE='Polyhedron Polyline_simplification_2 Polynomial ' - - PACKAGE='Polytope_distance_d Principal_component_analysis Principal_component_analysis_LGPL ' - - PACKAGE='Profiling_tools Property_map QP_solver ' - - PACKAGE='Random_numbers Ridges_3 STL_Extension ' - - PACKAGE='Scale_space_reconstruction_3 Scripts SearchStructures ' - - PACKAGE='Segment_Delaunay_graph_2 Segment_Delaunay_graph_Linf_2 Set_movable_separability_2 ' - - PACKAGE='Shape_detection Skin_surface_3 Snap_rounding_2 ' - - PACKAGE='Solver_interface Spatial_searching Spatial_sorting ' - - PACKAGE='Straight_skeleton_2 Stream_lines_2 Stream_support ' - - PACKAGE='Subdivision_method_3 Surface_mesh Surface_mesh_approximation ' - - PACKAGE='Surface_mesh_deformation Surface_mesh_parameterization Surface_mesh_segmentation ' - - PACKAGE='Surface_mesh_shortest_path Surface_mesh_simplification Surface_mesh_skeletonization ' - - PACKAGE='Surface_mesh_topology Surface_mesher Surface_sweep_2 ' - - PACKAGE='TDS_2 TDS_3 Testsuite ' - - PACKAGE='Tetrahedral_remeshing Three Triangulation ' - - PACKAGE='Triangulation_2 Triangulation_3 Union_find ' - - PACKAGE='Visibility_2 Voronoi_diagram_2 wininst ' -compiler: clang -install: - - echo "$PWD" - - if [ -n "$TRAVIS_PULL_REQUEST_BRANCH" ] && [ "$PACKAGE" != CHECK ]; then DO_IGNORE=FALSE; for ARG in $(echo "$PACKAGE");do if [ "$ARG" = "Maintenance" ]; then continue; fi; . $PWD/.travis/test_package.sh "$PWD" "$ARG"; echo "DO_IGNORE is $DO_IGNORE"; if [ "$DO_IGNORE" = "FALSE" ]; then break; fi; done; if [ "$DO_IGNORE" = "TRUE" ]; then travis_terminate 0; fi;fi - - /usr/bin/time -f 'Spend time of %C -- %E (real)' bash .travis/install.sh - - export CXX=clang++-10 CC=clang-10; -before_script: - - wget -O doxygen_exe https://cgal.geometryfactory.com/~mgimeno/doxygen_exe - - sudo mv doxygen_exe /usr/bin/doxygen - - sudo chmod +x /usr/bin/doxygen - - mkdir -p build - - cd build - - /usr/bin/time -f 'Spend time of %C -- %E (real)' cmake -DCMAKE_CXX_FLAGS="-std=c++1y" -DCGAL_HEADER_ONLY=ON -DCMAKE_CXX_FLAGS_RELEASE=-DCGAL_NDEBUG -DWITH_examples=ON -DWITH_demos=ON -DWITH_tests=ON .. - - /usr/bin/time -f 'Spend time of %C -- %E (real)' make - - /usr/bin/time -f 'Spend time of %C -- %E (real)' sudo make install &>/dev/null - - cd .. -script: - - cd ./.travis - - /usr/bin/time -f 'Spend time of %C -- %E (real)' bash ./build_package.sh $PACKAGE -notifications: - email: - on_success: change - # default: always - on_failure: always - # default: always diff --git a/.travis/build_package.sh b/.travis/build_package.sh deleted file mode 100755 index dc41aa16dd1..00000000000 --- a/.travis/build_package.sh +++ /dev/null @@ -1,144 +0,0 @@ -#!/bin/bash -set -e -[ -n "$CGAL_DEBUG_TRAVIS" ] && set -x - -CXX_FLAGS="-DCGAL_NDEBUG -ftemplate-backtrace-limit=0" - -function mytime { - /usr/bin/time -f "Spend time of %C: %E (real)" "$@" -} -old_IFS=$IFS -IFS=$' ' -ROOT="$PWD/.." -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 ] ||\ - [ "$ARG" = Polygon_mesh_processing ] || [ "$ARG" = Property_map ] ||\ - [ "$ARG" = Surface_mesh_deformation ] || [ "$ARG" = Surface_mesh_shortest_path ] ||\ - [ "$ARG" = Surface_mesh_simplification ]; then - mytime sudo bash .travis/install_openmesh.sh - fi - - - if [ "$ARG" = "CHECK" ] - then - cd .travis - mytime ./generate_travis.sh --check - cd .. - IFS=$old_IFS - mytime zsh $ROOT/Scripts/developer_scripts/test_merge_of_branch HEAD - #test dependencies - cd $ROOT - mytime bash Scripts/developer_scripts/cgal_check_dependencies.sh --check_headers /usr/bin/doxygen - - cd .travis - #parse current matrix and check that no package has been forgotten - - IFS=$'\n' - COPY=0 - MATRIX=() - for LINE in $(cat "$PWD/packages.txt") - do - MATRIX+="$LINE " - done - - PACKAGES=() - cd .. - for f in * - do - if [ -d "$f/package_info/$f" ] - then - PACKAGES+="$f " - fi - done - - DIFFERENCE=$(echo ${MATRIX[@]} ${PACKAGES[@]} | tr ' ' '\n' | sort | uniq -u) - IFS=$' ' - if [ "${DIFFERENCE[0]}" != "" ] - then - echo "The matrix and the actual package list differ : ." - echo ${DIFFERENCE[*]} - echo "You should run generate_travis.sh." - exit 1 - fi - echo "Matrix is up to date." - #check if non standard cgal installation works - cd $ROOT - mkdir build_test - cd build_test - mytime cmake -DCMAKE_INSTALL_PREFIX=install/ -DCGAL_BUILD_THREE_DOC=TRUE .. - mytime make install - # test install with minimal downstream example - mkdir installtest - cd installtest - touch main.cpp - mkdir build - echo 'project(Example)' >> CMakeLists.txt - echo 'set(PROJECT_SRCS ${PROJECT_SOURCE_DIR}/main.cpp)' >> CMakeLists.txt - echo 'find_package(CGAL REQUIRED)' >> CMakeLists.txt - echo 'add_executable(${PROJECT_NAME} ${PROJECT_SRCS})' >> CMakeLists.txt - echo 'target_link_libraries(${PROJECT_NAME} CGAL::CGAL)' >> CMakeLists.txt - echo '#include "CGAL/remove_outliers.h"' >> main.cpp - cd build - mytime cmake -DCMAKE_INSTALL_PREFIX=../../install -DCGAL_BUILD_THREE_DOC=TRUE .. - exit 0 - fi - - if [ "$ARG" = "Installation" ] - then - mkdir build_dir - cd build_dir - cmake -DWITH_tests=ON -DBUILD_TESTING=ON .. - ctest -j2 -L CGAL_cmake_testsuite --output-on-failure - cd .. - rm -rf ./build_dir - #==-- configure all CGAL with -DWITH_examples=ON -DWITH_demos=ON -DWITH_tests=ON, and then launch CTest on a few labels. --== - mkdir config_dir - cd config_dir - cmake -DWITH_examples=ON -DWITH_demos=ON -DWITH_tests=ON -DBUILD_TESTING=ON .. - ctest -j2 -L AABB_tree --output-on-failure - cd .. - rm -rf ./config_dir - exit 0 - fi - - IFS=$old_IFS - - if [ -n "$TRAVIS_PULL_REQUEST_BRANCH" ]; then - DO_IGNORE=FALSE - . $ROOT/.travis/test_package.sh "$ROOT" "$ARG" - echo "DO_IGNORE is $DO_IGNORE" - if [ "$DO_IGNORE" = "TRUE" ]; then - continue - fi - fi - IFS=$' ' - mkdir -p build-travis - cd build-travis - WITHDEMOS=ON - if [ "$ARG" = "Polyhedron" ]; then - WITHDEMOS=OFF - fi - EXTRA_CXX_FLAGS= - case "$CC" in - clang*) - EXTRA_CXX_FLAGS="-Werror=inconsistent-missing-override" - ;; - esac - - - mytime cmake -DCMAKE_CXX_FLAGS="${CXX_FLAGS} ${EXTRA_CXX_FLAGS}" -DCGAL_DONT_OVERRIDE_CMAKE_FLAGS:BOOL=ON -DBUILD_TESTING=ON -DWITH_tests=ON -DWITH_examples=ON -DWITH_demos=$WITHDEMOS .. - mytime ctest -j2 -L $ARG'([_][A-Z]|$)' -E execution___of__ --output-on-failure -done -IFS=$old_IFS -# Local Variables: -# tab-width: 2 -# sh-basic-offset: 2 -# End: diff --git a/.travis/generate_travis.sh b/.travis/generate_travis.sh deleted file mode 100755 index cef9ff07c49..00000000000 --- a/.travis/generate_travis.sh +++ /dev/null @@ -1,94 +0,0 @@ -#!/bin/bash - -CHECK= -case $1 in - --check) CHECK=y;; -esac - -set -e -cd ../ - -if [ -f "$PWD/.travis/packages.txt" ] -then - rm "$PWD/.travis/packages.txt" -fi - -#find all the packages -PACKAGES=() -INDEX=0 -i=0 -for f in * -do - if [ -d "$f/package_info/$f" ] - then - echo "$f" >> ./tmp.txt - fi -done - LC_ALL=C sort ./tmp.txt > ./.travis/packages.txt - rm ./tmp.txt - while read p; do - PACKAGES[$INDEX]+="$p " - i=$[i+1] - if [ $i = 3 ] - then - i=0 - INDEX=$[INDEX+1] - fi -done <./.travis/packages.txt -if [ -f ".travis.yml" ] -then - #copy the current .travis.yml for later check - mv ./.travis.yml ./.travis.old -fi -#writes the first part of the file -old_IFS=$IFS -IFS=$'\n' -for LINE in $(cat "$PWD/.travis/template.txt") -do - if [ "$LINE" != " matrix:" ] - then - echo "$LINE" >> .travis.yml - else - break - fi -done -echo " matrix:" >> .travis.yml -#writes the matrix -echo " - PACKAGE='CHECK'" >> .travis.yml -for package in ${PACKAGES[@]} -do -echo " - PACKAGE='$package'" >> .travis.yml -done - -#writes the end of the file -COPY=0 -for LINE in $(cat "$PWD/.travis/template.txt") -do - if [ "$LINE" = "compiler: clang" ] - then - COPY=1 - fi - if [ $COPY = 1 ] - then - echo "$LINE" >> .travis.yml - fi -done -IFS=$' ' -#check if there are differences between the files -if ! cmp -s ./.travis.yml ./.travis.old; -then - echo ".travis.yml has changed : " - diff ./.travis.yml ./.travis.old - if [ -n "$CHECK" ]; then - echo "You should modify the file .travis/template.txt" - exit 1 - fi -fi -#erase old travis -rm ./.travis.old -IFS=$old_IFS - -# Local Variables: -# tab-width: 2 -# sh-basic-offset: 2 -# End: diff --git a/.travis/install.sh b/.travis/install.sh deleted file mode 100644 index ec1791b750e..00000000000 --- a/.travis/install.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -[ -n "$CGAL_DEBUG_TRAVIS" ] && set -x -DONE=0 -sudo add-apt-repository ppa:mikhailnov/pulseeffects -y -sudo apt-get update - -while [ $DONE = 0 ] -do - DONE=1 && sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install clang-10 zsh \ -flex bison cmake graphviz libgmp-dev libmpfr-dev libmpfi-dev zlib1g-dev libeigen3-dev \ -qtbase5-dev libqt5sql5-sqlite libqt5opengl5-dev qtscript5-dev libqt5svg5-dev qttools5-dev qttools5-dev-tools qml-module-qtgraphicaleffects libopencv-dev mesa-common-dev libmetis-dev libglu1-mesa-dev \ -libboost1.72-dev || DONE=0 && sudo apt-get update -done -exit 0 - diff --git a/.travis/install_openmesh.sh b/.travis/install_openmesh.sh deleted file mode 100644 index 9b7a4f8e890..00000000000 --- a/.travis/install_openmesh.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -mkdir -p openmesh -cd openmesh -wget -O openmesh.tar.gz https://www.openmesh.org/media/Releases/6.3/OpenMesh-6.3.tar.gz -tar xf openmesh.tar.gz --strip-components=1 -sed -i '94i #include ' src/OpenMesh/Tools/Utils/conio.cc - -mkdir build -cd build -cmake -DBUILD_APPS=FALSE .. -make -j2 -sudo make -j2 install &>/dev/null - -#clean up -cd ../.. -rm -rf ./openmesh diff --git a/.travis/packages.txt b/.travis/packages.txt deleted file mode 100644 index b4874d76f4a..00000000000 --- a/.travis/packages.txt +++ /dev/null @@ -1,138 +0,0 @@ -AABB_tree -Advancing_front_surface_reconstruction -Algebraic_foundations -Algebraic_kernel_d -Algebraic_kernel_for_circles -Algebraic_kernel_for_spheres -Alpha_shapes_2 -Alpha_shapes_3 -Apollonius_graph_2 -Arithmetic_kernel -Arrangement_on_surface_2 -BGL -Barycentric_coordinates_2 -Boolean_set_operations_2 -Bounding_volumes -Box_intersection_d -CGAL_Core -CGAL_ImageIO -CGAL_ipelets -Cartesian_kernel -Circular_kernel_2 -Circular_kernel_3 -Circulator -Classification -Combinatorial_map -Cone_spanners_2 -Convex_decomposition_3 -Convex_hull_2 -Convex_hull_3 -Convex_hull_d -Distance_2 -Distance_3 -Envelope_2 -Envelope_3 -Filtered_kernel -Generalized_map -Generator -Geomview -GraphicsView -HalfedgeDS -Hash_map -Heat_method_3 -Homogeneous_kernel -Hyperbolic_triangulation_2 -Inscribed_areas -Installation -Interpolation -Intersections_2 -Intersections_3 -Interval_skip_list -Interval_support -Jet_fitting_3 -Kernel_23 -Kernel_d -LEDA -Linear_cell_complex -MacOSX -Maintenance -Matrix_search -Mesh_2 -Mesh_3 -Mesher_level -Minkowski_sum_2 -Minkowski_sum_3 -Modifier -Modular_arithmetic -Nef_2 -Nef_3 -Nef_S2 -NewKernel_d -Number_types -OpenNL -Optimal_bounding_box -Optimal_transportation_reconstruction_2 -Optimisation_basic -Partition_2 -Periodic_2_triangulation_2 -Periodic_3_mesh_3 -Periodic_3_triangulation_3 -Periodic_4_hyperbolic_triangulation_2 -Point_set_2 -Point_set_3 -Point_set_processing_3 -Poisson_surface_reconstruction_3 -Polygon -Polygon_mesh_processing -Polygonal_surface_reconstruction -Polyhedron -Polyline_simplification_2 -Polynomial -Polytope_distance_d -Principal_component_analysis -Principal_component_analysis_LGPL -Profiling_tools -Property_map -QP_solver -Random_numbers -Ridges_3 -STL_Extension -Scale_space_reconstruction_3 -Scripts -SearchStructures -Segment_Delaunay_graph_2 -Segment_Delaunay_graph_Linf_2 -Set_movable_separability_2 -Shape_detection -Skin_surface_3 -Snap_rounding_2 -Solver_interface -Spatial_searching -Spatial_sorting -Straight_skeleton_2 -Stream_lines_2 -Stream_support -Subdivision_method_3 -Surface_mesh -Surface_mesh_approximation -Surface_mesh_deformation -Surface_mesh_parameterization -Surface_mesh_segmentation -Surface_mesh_shortest_path -Surface_mesh_simplification -Surface_mesh_skeletonization -Surface_mesh_topology -Surface_mesher -Surface_sweep_2 -TDS_2 -TDS_3 -Testsuite -Tetrahedral_remeshing -Three -Triangulation -Triangulation_2 -Triangulation_3 -Union_find -Visibility_2 -Voronoi_diagram_2 -wininst diff --git a/.travis/template.txt b/.travis/template.txt deleted file mode 100644 index 3b99af1ff13..00000000000 --- a/.travis/template.txt +++ /dev/null @@ -1,34 +0,0 @@ -language: cpp -dist: bionic -sudo: required -git: - depth: 3 -env: - matrix: - PACKAGES_MATRIX - -compiler: clang -install: - - echo "$PWD" - - if [ -n "$TRAVIS_PULL_REQUEST_BRANCH" ] && [ "$PACKAGE" != CHECK ]; then DO_IGNORE=FALSE; for ARG in $(echo "$PACKAGE");do if [ "$ARG" = "Maintenance" ]; then continue; fi; . $PWD/.travis/test_package.sh "$PWD" "$ARG"; echo "DO_IGNORE is $DO_IGNORE"; if [ "$DO_IGNORE" = "FALSE" ]; then break; fi; done; if [ "$DO_IGNORE" = "TRUE" ]; then travis_terminate 0; fi;fi - - /usr/bin/time -f 'Spend time of %C -- %E (real)' bash .travis/install.sh - - export CXX=clang++-10 CC=clang-10; -before_script: - - wget -O doxygen_exe https://cgal.geometryfactory.com/~mgimeno/doxygen_exe - - sudo mv doxygen_exe /usr/bin/doxygen - - sudo chmod +x /usr/bin/doxygen - - mkdir -p build - - cd build - - /usr/bin/time -f 'Spend time of %C -- %E (real)' cmake -DCMAKE_CXX_FLAGS="-std=c++1y" -DCGAL_HEADER_ONLY=ON -DCMAKE_CXX_FLAGS_RELEASE=-DCGAL_NDEBUG -DWITH_examples=ON -DWITH_demos=ON -DWITH_tests=ON .. - - /usr/bin/time -f 'Spend time of %C -- %E (real)' make - - /usr/bin/time -f 'Spend time of %C -- %E (real)' sudo make install &>/dev/null - - cd .. -script: - - cd ./.travis - - /usr/bin/time -f 'Spend time of %C -- %E (real)' bash ./build_package.sh $PACKAGE -notifications: - email: - on_success: change - # default: always - on_failure: always - # default: always diff --git a/.travis/test_package.sh b/.travis/test_package.sh deleted file mode 100644 index 7b01d24ceb4..00000000000 --- a/.travis/test_package.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -#Will cd $1 and test package named $2 -#to find out if it or one of its dependencies has changed in the current branch - -DO_IGNORE=FALSE -cd $1 - -if [ ! -d "$2" ]; then - echo "$2 : MISSING PACKAGE. Ignoring." - DO_IGNORE=TRUE - exit 1 -fi - - -if [ ! -f "$2/package_info/$2/dependencies" ];then - echo "No dependencies found for $2" - bash Scripts/developer_scripts/cgal_check_dependencies.sh --check_headers /usr/bin/doxygen - exit 1 -fi -LIST_OF_FILES=$(git diff --name-only origin/master... |cut -d/ -f1 |uniq |sort) -LIST_OF_DEPS=$(cat "$2/package_info/$2/dependencies") -echo "$LIST_OF_DEPS" -for flie in $LIST_OF_DEPS -do - [[ $LIST_OF_FILES =~ (^|[[:space:]])$flie($|[[:space:]]) ]] && return -done -echo "Package ignored because none of its dependencies has been modified." -DO_IGNORE=TRUE - diff --git a/.travis/windows.h b/.travis/windows.h deleted file mode 100644 index a774a068df3..00000000000 --- a/.travis/windows.h +++ /dev/null @@ -1,12 +0,0 @@ -#define MAX(a,b) (((a) > (b)) ? (a) : (b)) -#define max(a,b) (((a) > (b)) ? (a) : (b)) - -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -#define min(a,b) (((a) < (b)) ? (a) : (b)) - - -#define FAR #error named reserved in windows.h -#define far #error named reserved in windows.h - -#define Polyline #error named reserved in windows.h -#define Polygon #error named reserved in windows.h diff --git a/AABB_tree/include/CGAL/AABB_traits.h b/AABB_tree/include/CGAL/AABB_traits.h index 613d08c174b..e443e08a522 100644 --- a/AABB_tree/include/CGAL/AABB_traits.h +++ b/AABB_tree/include/CGAL/AABB_traits.h @@ -428,6 +428,11 @@ public: Closest_point closest_point_object() const {return Closest_point(*this);} Compare_distance compare_distance_object() const {return Compare_distance();} + typedef enum { CGAL_AXIS_X = 0, + CGAL_AXIS_Y = 1, + CGAL_AXIS_Z = 2} Axis; + + static Axis longest_axis(const Bounding_box& bbox); private: /** @@ -446,13 +451,6 @@ private: return internal::Primitive_helper::get_datum(pr,*this).bbox(); } - - typedef enum { CGAL_AXIS_X = 0, - CGAL_AXIS_Y = 1, - CGAL_AXIS_Z = 2} Axis; - - static Axis longest_axis(const Bounding_box& bbox); - /// Comparison functions static bool less_x(const Primitive& pr1, const Primitive& pr2,const AABB_traits& traits) { diff --git a/AABB_tree/include/CGAL/AABB_tree.h b/AABB_tree/include/CGAL/AABB_tree.h index 5f0521e219f..1bb4d0b2d17 100644 --- a/AABB_tree/include/CGAL/AABB_tree.h +++ b/AABB_tree/include/CGAL/AABB_tree.h @@ -126,7 +126,7 @@ namespace CGAL { Self& operator=(const Self&) = delete; /** - * @brief Builds the datastructure from a sequence of primitives. + * @brief Builds the data structure from a sequence of primitives. * @param first iterator over first primitive to insert * @param beyond past-the-end iterator * diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Concepts/AdvancingFrontSurfaceReconstructionTraits_3.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Concepts/AdvancingFrontSurfaceReconstructionTraits_3.h new file mode 100644 index 00000000000..458f63668af --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Concepts/AdvancingFrontSurfaceReconstructionTraits_3.h @@ -0,0 +1,159 @@ + +/*! +\ingroup PkgAdvancingFrontSurfaceReconstructionRef +\cgalConcept + +The concept `AdvancingFrontSurfaceReconstructionTraits_3` describes the requirements +for the the geometric traits of the class `CGAL::Delaunay_triangulation_3` +used in the class `CGAL::Advancing_front_surface_reconstruction`. +It defines the geometric objects (points, segments...) forming the triangulation +together with a few geometric predicates and constructions on these objects. + +\cgalRefines `DelaunayTriangulationTraits_3` + +\cgalHasModel All models of `Kernel`. +*/ +class AdvancingFrontSurfaceReconstructionTraits_3 +{ +public: + +/// \name Types +/// @{ + +/*! +The coordinate type. +*/ +typedef unspecified_type FT; + +/*! +The vector type. +*/ +typedef unspecified_type Vector_3; + +/*! +The sphere type. +*/ +typedef unspecified_type Sphere_3; + +/*! +A constructor object that must provide the function operator + +`Vector_3 operator()(Point_3 p, Point_3 q)`, + +which constructs the vector `q-p`. +*/ +typedef unspecified_type Construct_vector_3; + +/*! +A constructor object that must provide the function operator + +`Vector_3 operator()(Vector_3 v, Vector_3 w)`, + +which returns the cross product of `v` and `w`. +*/ +typedef unspecified_type Construct_cross_product_vector_3; + +/*! +A constructor object that must provide the function operator + +`FT operator()(Vector_3 v, Vector_3 w)`, + +which returns the scalar (inner) product of `v` and `w`. +*/ +typedef unspecified_type Compute_scalar_product_3; + +/*! +A constructor object that must provide the function operator + +`Sphere_3 operator()(Point_3 p, Point_3 q, Point_3 r)`, + +which constructs a sphere initialized to the smallest sphere which passes +through the points `p`, `q`, and `r`. +*/ +typedef unspecified_type Construct_sphere_3; + +/*! +A constructor object that must provide the function operator + +`Point_3 operator()(Sphere_3 s)`, + +which returns the center of the sphere `s`. +*/ +typedef unspecified_type Construct_center_3; + +/*! +A constructor object that must provide the function operators + +`FT operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 s)`, + +which returns the squared radius of the sphere passing through `p`, `q` and `r`, +and whose center is in the plane defined by these three points. + +and + +`FT operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 s)`, + +which returns the squared radius of the sphere passing through `p`, `q`, `r`, and `s`. + +and + +`FT operator()(Sphere_3 s)`, + +which returns the squared radius of the sphere `s`. +*/ +typedef unspecified_type Compute_squared_radius_3; + +/*! +A constructor object that must provide the function operator + +`FT operator()(Point_3 p, Point_3 q)`, + +which returns the squared distance between the points `p` and `q`. +*/ +typedef unspecified_type Compute_squared_distance_3; + +/// @} + +/// \name Operations +/// The following functions give access to the predicate and construction objects: +/// @{ + +/*! +gives access to the `Construct_vector_3` construction. +*/ +Construct_vector_3 construct_vector_3_object(); + +/*! +gives access to the `Construct_cross_product_vector_3` construction. +*/ +Construct_cross_product_vector_3 construct_cross_product_vector_3_object(); + +/*! +gives access to the `Compute_scalar_product_3` construction. +*/ +Compute_scalar_product_3 compute_scalar_product_3_object(); + +/*! +gives access to the `Construct_sphere_3` construction. +*/ +Construct_sphere_3 construct_sphere_3_object(); + +/*! +gives access to the `Construct_center_3` construction. +*/ +Construct_center_3 construct_center_3_object(); + +/*! +gives access to the `Compute_squared_radius_3` construction. +*/ +Compute_squared_radius_3 compute_squared_radius_3_object(); + +/*! +gives access to the `Compute_squared_distance_3` construction. +*/ +Compute_squared_distance_3 compute_squared_distance_3_object(); + +/// @} + +}; /* end AdvancingFrontSurfaceReconstructionTraits_3 */ + diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt index 1adb33ca94e..5d50c10442c 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt @@ -1,5 +1,8 @@ /// \defgroup PkgAdvancingFrontSurfaceReconstructionRef Advancing Front Surface Reconstruction Reference +/// \defgroup PkgAdvancingFrontSurfaceReconstructionRefConcepts Concepts +/// \ingroup PkgAdvancingFrontSurfaceReconstructionRef + /*! \addtogroup PkgAdvancingFrontSurfaceReconstructionRef @@ -25,6 +28,10 @@ of topological singularities. } \cgalClassifedRefPages +\cgalCRPSection{Concepts} + +- `AdvancingFrontSurfaceReconstructionTraits_3` + \cgalCRPSection{Classes} - `CGAL::Advancing_front_surface_reconstruction` diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies index 9b91259b814..69d8724660e 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies @@ -5,6 +5,7 @@ Algebraic_foundations Circulator Stream_support TDS_2 +TDS_3 Triangulation_2 Triangulation_3 Number_types diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index e997bd55870..a54eaf9db24 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -175,23 +175,42 @@ namespace CGAL { store handles to the vertices and faces of the 3D triangulation, which enables the user to explore the 2D as well as 3D neighborhood of vertices and facets of the surface. - \tparam Dt must be a `Delaunay_triangulation_3` with - `Advancing_front_surface_reconstruction_vertex_base_3` and `Advancing_front_surface_reconstruction_cell_base_3` blended into the vertex and cell type. - The default uses the `Exact_predicates_inexact_constructions_kernel` as geometric traits class. + \tparam Dt must be a `Delaunay_triangulation_3` whose `Traits` template parameter must be a model of + `AdvancingFrontSurfaceReconstructionTraits_3` and whose `Tds` template parameter must be + a model of `TriangulationDataStructure_3` with `Advancing_front_surface_reconstruction_vertex_base_3` and + `Advancing_front_surface_reconstruction_cell_base_3` blended into the vertex and cell type, respectively. + The default value is: + \code + CGAL::Delaunay_triangulation_3, + CGAL::Advancing_front_surface_reconstruction_cell_base_3< + CGAL::Exact_predicates_inexact_constructions_kernel> > >` + \endcode - \tparam P must be a functor with `double operator()(AdvancingFront,Cell_handle,int)` returning the - priority of the facet `(Cell_handle,int)`. This functor enables the user to choose how candidate - triangles are prioritized. If a facet should not appear in the output, + \tparam P must be a functor offering + \code + FT operator()(Advancing_front_surface_reconstruction,Cell_handle,int) + \endcode + returning the priority of the facet `(Cell_handle,int)`. This functor enables the user + to choose how candidate triangles are prioritized. If a facet should not appear in the output, `infinity()` must be returned. It defaults to a functor that returns the `smallest_radius_delaunay_sphere()`. */ - template < - class Dt = Default, - class P = Default> - class Advancing_front_surface_reconstruction { - - typedef typename Default::Get, Advancing_front_surface_reconstruction_cell_base_3 > > >::type Triangulation; + template + class Advancing_front_surface_reconstruction + { + typedef typename Default::Get, + Advancing_front_surface_reconstruction_cell_base_3< + Exact_predicates_inexact_constructions_kernel> > > >::type Triangulation; typedef typename Default::Get::type Priority; public: @@ -202,9 +221,9 @@ namespace CGAL { /*! The type of the 2D triangulation data structure describing the reconstructed surface, being a model of `TriangulationDataStructure_2`. - The type `Triangulation_data_structure_2::Vertex` is model of the concept `TriangulationDataStructure_2::Vertex` and has additionally the - method `vertex_3()` that returns a `#Vertex_handle` to the associated 3D vertex. + method `vertex_3()` that returns a `Vertex_handle` to the associated 3D vertex. - The type `Triangulation_data_structure_2::Face` is model of the concept `TriangulationDataStructure_2::Face` and has additionally the - method `facet()` that returns the associated `#Facet`, and a method `bool is_on_surface()` + method `facet()` that returns the associated `Facet`, and a method `bool is_on_surface()` for testing if a face is part of the reconstructed surface or a face incident to a boundary edge. In case the surface has boundaries, the 2D surface has one vertex which is associated to the infinite @@ -213,15 +232,20 @@ namespace CGAL { typedef unspecified_type Triangulation_data_structure_2; /*! - The type of the 3D triangulation. + The type of the 3D Delaunay triangulation (the first template parameter). */ typedef unspecified_type Triangulation_3; /*! - The type of the facet priority functor. + The type of the facet priority functor (the second template parameter). */ typedef unspecified_type Priority; + /*! + The number type. + */ + typedef typename Triangulation_3::Geom_traits::FT FT; + /*! The point type. */ @@ -245,21 +269,21 @@ namespace CGAL { /*! A bidirectional iterator range which enables to enumerate all points that were removed from the 3D Delaunay triangulation during the surface reconstruction. The value type - of the iterator is `#Point`. + of the iterator is `Point`. */ typedef unspecified_type Outlier_range; + /*! + A bidirectional iterator range which enables to visit all vertices on a boundary. + The value type of the iterator is `Vertex_handle`. + */ + typedef unspecified_type Vertex_on_boundary_range; + /*! A bidirectional iterator range which enables to visit all boundaries. The value type of the iterator is `Vertex_on_boundary_range`. */ typedef unspecified_type Boundary_range; - - /*! - A bidirectional iterator range which enables to visit all vertices on a boundary. - The value type of the iterator is `#Vertex_handle` - */ - typedef unspecified_type Vertex_on_boundary_range; /// @} #endif @@ -268,6 +292,7 @@ namespace CGAL { typedef Advancing_front_surface_reconstruction Extract; typedef typename Triangulation_3::Geom_traits Geom_traits; + typedef typename Kernel::FT FT; typedef typename Kernel::FT coord_type; typedef typename Kernel::Point_3 Point; @@ -377,7 +402,23 @@ namespace CGAL { std::list nbe_pool; std::list ist_pool; + public: + Vector construct_vector(const Point& p, const Point& q) const + { + return T.geom_traits().construct_vector_3_object()(p, q); + } + Vector construct_cross_product(const Vector& v, const Vector& w) const + { + return T.geom_traits().construct_cross_product_vector_3_object()(v, w); + } + + FT compute_scalar_product(const Vector& v, const Vector& w) const + { + return T.geom_traits().compute_scalar_product_3_object()(v, w); + } + + private: Intern_successors_type* new_border() { nbe_pool.resize(nbe_pool.size()+1); @@ -679,12 +720,14 @@ namespace CGAL { ++it; }while(collinear(p,q,it->point())); const Point& r = it->point(); - Vector u = q-r; - Vector v = q-p; - Vector w = r-p; - Vector vw = cross_product(v,w); - double len = (std::max)(u*u,(std::max)(v*v,w*w)); - Point s = p + 10* len * (vw/(vw*vw)); + Vector u = construct_vector(r, q); + Vector v = construct_vector(p, q); + Vector w = construct_vector(p, r); + Vector vw = construct_cross_product(v,w); + double len = (std::max)(compute_scalar_product(u,u), + (std::max)(compute_scalar_product(v,v), + compute_scalar_product(w,w))); + Point s = p + 10 * len * (vw/compute_scalar_product(vw,vw)); added_vertex = T.insert(s); } } @@ -736,9 +779,9 @@ namespace CGAL { \param radius_ratio_bound candidates incident to surface triangles which are not in the beta-wedge are discarded, if the ratio of their radius and the radius of the surface triangle is larger than `radius_ratio_bound`. - Described in Section \ref AFSR_Boundaries + Described in Section \ref AFSR_Boundaries. \param beta half the angle of the wedge in which only the radius of triangles counts for the plausibility of candidates. - Described in Section \ref AFSR_Selection + Described in Section \ref AFSR_Selection. */ void run(double radius_ratio_bound=5, double beta= 0.52) @@ -1186,7 +1229,7 @@ namespace CGAL { \param index index of the facet in `c` */ - coord_type + FT smallest_radius_delaunay_sphere(const Cell_handle& c, const int& index) const { @@ -1249,16 +1292,16 @@ namespace CGAL { const Point& pp2 = cc->vertex(i2)->point(); const Point& pp3 = cc->vertex(i3)->point(); - Sphere facet_sphere(pp1, pp2, pp3); - if (squared_distance(facet_sphere.center(), pp0) < - facet_sphere.squared_radius()) + Sphere facet_sphere = T.geom_traits().construct_sphere_3_object()(pp1, pp2, pp3); + if (squared_distance(T.geom_traits().construct_center_3_object()(facet_sphere), pp0) < + T.geom_traits().compute_squared_radius_3_object()(facet_sphere)) { #ifdef AFSR_LAZY value = lazy_squared_radius(cc); #else // qualified with CGAL, to avoid a compilation error with clang if(volume(pp0, pp1, pp2, pp3) != 0){ - value = CGAL::squared_radius(pp0, pp1, pp2, pp3); + value = T.geom_traits().compute_squared_radius_3_object()(pp0, pp1, pp2, pp3); } else { typedef Exact_predicates_exact_constructions_kernel EK; Cartesian_converter to_exact; @@ -1280,26 +1323,30 @@ namespace CGAL { cc = lazy_circumcenter(c); cn = lazy_circumcenter(n); #else - cc = CGAL::circumcenter(cp0, cp1, cp2, cp3); - cn = CGAL::circumcenter(np0, np1, np2, np3); + cc = T.geom_traits().construct_circumcenter_3_object()(cp0, cp1, cp2, cp3); + cn = T.geom_traits().construct_circumcenter_3_object()(np0, np1, np2, np3); #endif // computation of the distance of cp1 to the dual segment cc, cn... - Vector V(cc - cn), Vc(cc - cp1), Vn(cp1 - cn); - coord_type ac(V * Vc), an(V * Vn), norm_V(V * V); + Vector V = construct_vector(cn, cc), + Vc = construct_vector(cp1, cc), + Vn = construct_vector(cn, cp1); + coord_type ac = compute_scalar_product(V, Vc), + an = compute_scalar_product(V, Vn), + norm_V = compute_scalar_product(V, V); if ((ac > 0) && (an > 0)) { - value = (Vc*Vc) - ac*ac/norm_V; + value = compute_scalar_product(Vc, Vc) - ac*ac/norm_V; if ((value < 0)||(norm_V > inv_eps_2)){ // qualified with CGAL, to avoid a compilation error with clang - value = CGAL::squared_radius(cp1, cp2, cp3); + value = T.geom_traits().compute_squared_radius_3_object()(cp1, cp2, cp3); } } else { if (ac <= 0) - value = squared_distance(cc, cp1); + value = T.geom_traits().compute_squared_distance_3_object()(cc, cp1); else // (an <= 0) - value = squared_distance(cn, cp1); + value = T.geom_traits().compute_squared_distance_3_object()(cn, cp1); } } } @@ -1314,7 +1361,7 @@ namespace CGAL { returns the infinite floating value that prevents a facet to be used. */ - coord_type infinity() const { return std::numeric_limits::infinity(); } + FT infinity() const { return std::numeric_limits::infinity(); } /// @} //--------------------------------------------------------------------- @@ -1341,9 +1388,9 @@ namespace CGAL { const Point& p2 = c->vertex(i2)->point(); const Point& pc = c->vertex(i3)->point(); - Vector P2P1 = p1-p2, P2Pn, PnP1; + Vector P2P1 = construct_vector(p2, p1), P2Pn, PnP1; - Vector v2, v1 = cross_product(pc-p2, P2P1); + Vector v2, v1 = construct_cross_product(construct_vector(p2, pc), P2P1); coord_type norm, norm1 = v1*v1; coord_type norm12 = P2P1*P2P1; @@ -1375,12 +1422,12 @@ namespace CGAL { { const Point& pn = neigh->vertex(n_i3)->point(); - P2Pn = pn-p2; - v2 = cross_product(P2P1,P2Pn); + P2Pn = construct_vector(p2, pn); + v2 = construct_cross_product(P2P1,P2Pn); //pas necessaire de normer pour un bon echantillon: // on peut alors tester v1*v2 >= 0 - norm = sqrt(norm1 * (v2*v2)); + norm = sqrt(norm1 * compute_scalar_product(v2,v2)); pscal = v1*v2; // check if the triangle will produce a sliver on the surface bool sliver_facet = (pscal <= COS_ALPHA_SLIVER*norm); @@ -1394,10 +1441,9 @@ namespace CGAL { // We skip triangles having an internal angle along e // whose cosinus is smaller than -DELTA // that is the angle is larger than arcos(-DELTA) - border_facet = !((P2P1*P2Pn >= - -DELTA*sqrt(norm12*(P2Pn*P2Pn)))&& - (P2P1*PnP1 >= - -DELTA*sqrt(norm12*(PnP1*PnP1)))); + border_facet = + !((P2P1*P2Pn >= -DELTA*sqrt(norm12*compute_scalar_product(P2Pn,P2Pn))) && + (P2P1*PnP1 >= -DELTA*sqrt(norm12*compute_scalar_product(PnP1,PnP1)))); // \todo investigate why we simply do not skip this triangle // but continue looking for a better candidate // if (!border_facet){ @@ -1569,9 +1615,11 @@ namespace CGAL { int n_i3 = (6 - n_ind - n_i1 - n_i2); const Point& pn = neigh->vertex(n_i3)->point(); - Vector v1 = cross_product(pc-p2,p1-p2), - v2 = cross_product(p1-p2,pn-p2); - coord_type norm = sqrt((v1*v1)*(v2*v2)); + Vector v1 = construct_cross_product(construct_vector(p2, pc), + construct_vector(p2, p1)), + v2 = construct_cross_product(construct_vector(p2, p1), + construct_vector(p2, pn)); + coord_type norm = sqrt(compute_scalar_product(v1, v1) * compute_scalar_product(v2, v2)); if (v1*v2 > COS_BETA*norm) return 1; // label bonne pliure sinon: @@ -2487,9 +2535,9 @@ namespace CGAL { \param out output iterator \param radius_ratio_bound candidates incident to surface triangles which are not in the beta-wedge are discarded, if the ratio of their radius and the radius of the surface triangle is larger than `radius_ratio_bound`. - Described in Section \ref AFSR_Boundaries + Described in Section \ref AFSR_Boundaries. \param beta half the angle of the wedge in which only the radius of triangles counts for the plausibility of candidates. - Described in Section \ref AFSR_Selection + Described in Section \ref AFSR_Selection. */ template @@ -2533,7 +2581,7 @@ namespace CGAL { be convertible to `Exact_predicates_inexact_constructions_kernel::Point_3` with the `Cartesian_converter`. \tparam IndicesOutputIterator must be an output iterator to which `std::array` can be assigned. - \tparam Priority must be a functor with `double operator()(AdvancingFront,Cell_handle,int)` returning the + \tparam Priority must be a functor with `double operator()(Advancing_front_surface_reconstruction,Cell_handle,int)` returning the priority of the facet `(Cell_handle,int)`. \param b iterator on the first point of the sequence diff --git a/Algebraic_foundations/doc/Algebraic_foundations/CGAL/number_utils.h b/Algebraic_foundations/doc/Algebraic_foundations/CGAL/number_utils.h index f81aa3945c2..74d7c452e99 100644 --- a/Algebraic_foundations/doc/Algebraic_foundations/CGAL/number_utils.h +++ b/Algebraic_foundations/doc/Algebraic_foundations/CGAL/number_utils.h @@ -22,7 +22,7 @@ namespace CGAL { \ingroup PkgAlgebraicFoundationsRef The template function `compare()` compares the first argument with respect to -the second, i.e.\ it returns `CGAL::LARGER` if \f$ x\f$ is larger then \f$ y\f$. +the second, i.e.\ it returns `CGAL::LARGER` if \f$ x\f$ is larger than \f$ y\f$. In case the argument types `NT1` and `NT2` differ, `compare` is performed with the semantic of the type determined via diff --git a/Algebraic_kernel_d/examples/Algebraic_kernel_d/CMakeLists.txt b/Algebraic_kernel_d/examples/Algebraic_kernel_d/CMakeLists.txt index 63cf6965333..b4bf51d141f 100644 --- a/Algebraic_kernel_d/examples/Algebraic_kernel_d/CMakeLists.txt +++ b/Algebraic_kernel_d/examples/Algebraic_kernel_d/CMakeLists.txt @@ -5,23 +5,15 @@ find_package(CGAL REQUIRED COMPONENTS Core) find_package(MPFI QUIET) -if(MPFI_FOUND) - +if(MPFI_FOUND AND NOT CGAL_DISABLE_GMP) include(${CGAL_USE_FILE}) include(${MPFI_USE_FILE}) include(CGAL_VersionUtils) - create_single_source_cgal_program("Compare_1.cpp") create_single_source_cgal_program("Construct_algebraic_real_1.cpp") create_single_source_cgal_program("Isolate_1.cpp") create_single_source_cgal_program("Sign_at_1.cpp") create_single_source_cgal_program("Solve_1.cpp") - else() - - message( - STATUS - "This program requires the CGAL library and MPFI, and will not be compiled." - ) - + message(STATUS "This program requires the CGAL, CGAL_Core and MPFI libraries, and will not be compiled.") endif() diff --git a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Curve_analysis_2.h b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Curve_analysis_2.h index 188610dac44..34290afa7e2 100644 --- a/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Curve_analysis_2.h +++ b/Algebraic_kernel_d/include/CGAL/Algebraic_kernel_d/Curve_analysis_2.h @@ -2007,7 +2007,7 @@ public: * * For each status line at an event and each status line that represents * an interval, all y-coordinates are approximated such that their - * isolating interval has absolute size smaller then \c precision. + * isolating interval has absolute size smaller than \c precision. */ void refine_all(Bound precision) { diff --git a/Algebraic_kernel_d/test/Algebraic_kernel_d/CMakeLists.txt b/Algebraic_kernel_d/test/Algebraic_kernel_d/CMakeLists.txt index b48f6a7e334..1338dba14ff 100644 --- a/Algebraic_kernel_d/test/Algebraic_kernel_d/CMakeLists.txt +++ b/Algebraic_kernel_d/test/Algebraic_kernel_d/CMakeLists.txt @@ -34,32 +34,36 @@ include(${CGAL_USE_FILE}) # ########################################################## create_single_source_cgal_program("cyclic.cpp") -create_single_source_cgal_program("Algebraic_curve_kernel_2.cpp") -create_single_source_cgal_program("algebraic_curve_kernel_2_tools.cpp") -create_single_source_cgal_program("Algebraic_kernel_d_1_LEDA.cpp") - -create_single_source_cgal_program( - "Algebraic_kernel_d_1_CORE_Integer_rational.cpp") -create_single_source_cgal_program( - "Algebraic_kernel_d_1_CORE_SqrtII_rational.cpp") -create_single_source_cgal_program( - "Algebraic_kernel_d_1_CORE_SqrtRI_rational.cpp") -create_single_source_cgal_program( - "Algebraic_kernel_d_1_CORE_SqrtRR_rational.cpp") - -create_single_source_cgal_program("Algebraic_kernel_d_1_GMP.cpp") -create_single_source_cgal_program("Algebraic_kernel_d_2.cpp") -create_single_source_cgal_program("Algebraic_real_d_1.cpp") -create_single_source_cgal_program("Bitstream_descartes.cpp") -create_single_source_cgal_program("Curve_analysis_2.cpp") -create_single_source_cgal_program("Curve_pair_analysis_2.cpp") create_single_source_cgal_program("Descartes.cpp") -create_single_source_cgal_program("Real_embeddable_traits_extension.cpp") -if(RS_FOUND) - create_single_source_cgal_program("Algebraic_kernel_rs_gmpq_d_1.cpp") - create_single_source_cgal_program("Algebraic_kernel_rs_gmpz_d_1.cpp") +if(NOT CGAL_DISABLE_GMP) + create_single_source_cgal_program("Algebraic_curve_kernel_2.cpp") + create_single_source_cgal_program("algebraic_curve_kernel_2_tools.cpp") + create_single_source_cgal_program("Algebraic_kernel_d_1_LEDA.cpp") + + create_single_source_cgal_program( + "Algebraic_kernel_d_1_CORE_Integer_rational.cpp") + create_single_source_cgal_program( + "Algebraic_kernel_d_1_CORE_SqrtII_rational.cpp") + create_single_source_cgal_program( + "Algebraic_kernel_d_1_CORE_SqrtRI_rational.cpp") + create_single_source_cgal_program( + "Algebraic_kernel_d_1_CORE_SqrtRR_rational.cpp") + + create_single_source_cgal_program("Algebraic_kernel_d_1_GMP.cpp") + create_single_source_cgal_program("Algebraic_kernel_d_2.cpp") + create_single_source_cgal_program("Algebraic_real_d_1.cpp") + create_single_source_cgal_program("Bitstream_descartes.cpp") + create_single_source_cgal_program("Curve_analysis_2.cpp") + create_single_source_cgal_program("Curve_pair_analysis_2.cpp") + create_single_source_cgal_program("Real_embeddable_traits_extension.cpp") + if(RS_FOUND) + create_single_source_cgal_program("Algebraic_kernel_rs_gmpq_d_1.cpp") + create_single_source_cgal_program("Algebraic_kernel_rs_gmpz_d_1.cpp") + else() + message( + STATUS + "NOTICE: Some tests require the RS library, and will not be compiled.") + endif() else() - message( - STATUS - "NOTICE: Some tests require the RS library, and will not be compiled.") + message(STATUS "NOTICE: Some tests require the CGAL_Core library, and will not be compiled.") endif() diff --git a/Algebraic_kernel_for_spheres/include/CGAL/Algebraic_kernel_for_spheres/internal_functions_comparison_root_for_spheres_2_3.h b/Algebraic_kernel_for_spheres/include/CGAL/Algebraic_kernel_for_spheres/internal_functions_comparison_root_for_spheres_2_3.h index 1bfca81e065..1a79af038cc 100644 --- a/Algebraic_kernel_for_spheres/include/CGAL/Algebraic_kernel_for_spheres/internal_functions_comparison_root_for_spheres_2_3.h +++ b/Algebraic_kernel_for_spheres/include/CGAL/Algebraic_kernel_for_spheres/internal_functions_comparison_root_for_spheres_2_3.h @@ -30,19 +30,19 @@ namespace CGAL { template Comparison_result compare_x(const CGAL::Root_for_spheres_2_3& r1, const CGAL::Root_for_spheres_2_3& r2){ - return compare(r1.x(), r2.x()); + return CGAL::compare(r1.x(), r2.x()); } template Comparison_result compare_y(const CGAL::Root_for_spheres_2_3& r1, const CGAL::Root_for_spheres_2_3& r2){ - return compare(r1.y(), r2.y()); + return CGAL::compare(r1.y(), r2.y()); } template Comparison_result compare_z(const CGAL::Root_for_spheres_2_3& r1, const CGAL::Root_for_spheres_2_3& r2){ - return compare(r1.z(), r2.z()); + return CGAL::compare(r1.z(), r2.z()); } template diff --git a/Alpha_shapes_2/doc/Alpha_shapes_2/Alpha_shapes_2.txt b/Alpha_shapes_2/doc/Alpha_shapes_2/Alpha_shapes_2.txt index 545d92b3924..251b466a0da 100644 --- a/Alpha_shapes_2/doc/Alpha_shapes_2/Alpha_shapes_2.txt +++ b/Alpha_shapes_2/doc/Alpha_shapes_2/Alpha_shapes_2.txt @@ -134,9 +134,8 @@ All \cgal kernels are models of both concepts. The triangulation data structure of the triangulation has to be a model of the concept `TriangulationDataStructure_2`, -and it must be parameterized with -vertex and face classes which are models of the concepts -`AlphaShapeVertex_2` and `AlphaShapeFace_2`. +whose vertex and face classes are models of the concepts +`AlphaShapeVertex_2` and `AlphaShapeFace_2`, respectively. The classes `Alpha_shape_vertex_base_2` and `Alpha_shape_face_base_2` are models of these concepts and can be used for all type of alpha shapes, provided that the template parameters `Vb` and `Fb` are appropriately chosen, diff --git a/Alpha_shapes_2/doc/Alpha_shapes_2/CGAL/Weighted_alpha_shape_euclidean_traits_2.h b/Alpha_shapes_2/doc/Alpha_shapes_2/CGAL/Weighted_alpha_shape_euclidean_traits_2.h deleted file mode 100644 index b182ba9e388..00000000000 --- a/Alpha_shapes_2/doc/Alpha_shapes_2/CGAL/Weighted_alpha_shape_euclidean_traits_2.h +++ /dev/null @@ -1,26 +0,0 @@ - -namespace CGAL { - -/*! -\ingroup PkgAlphaShapes2Ref - -\deprecated The class is deprecated since \cgal 4.10, as the weighted point and the function -objects for weighted points are part of the concept `Kernel`. The class is kept for backward -compatibility. - -The class `Weighted_alpha_shape_euclidean_traits_2` was the default model for the concept -`AlphaShapeTraits_2` for the regular version of Alpha Shapes. - -\tparam K must be a model of `Kernel`. - -\cgalModels `AlphaShapeTraits_2` - -*/ -template< typename K > -class Weighted_alpha_shape_euclidean_traits_2 - : public K -{ -public: - -}; /* end Weighted_alpha_shape_euclidean_traits_2 */ -} /* end namespace CGAL */ diff --git a/Alpha_shapes_2/doc/Alpha_shapes_2/Concepts/WeightedAlphaShapeTraits_2.h b/Alpha_shapes_2/doc/Alpha_shapes_2/Concepts/WeightedAlphaShapeTraits_2.h index 6a7dab82f54..ad7070f9a42 100644 --- a/Alpha_shapes_2/doc/Alpha_shapes_2/Concepts/WeightedAlphaShapeTraits_2.h +++ b/Alpha_shapes_2/doc/Alpha_shapes_2/Concepts/WeightedAlphaShapeTraits_2.h @@ -45,7 +45,7 @@ typedef unspecified_type FT; /*! A default constructor. */ - AlphaShapeTraits_2(); + WeightedAlphaShapeTraits_2(); /// @} diff --git a/Alpha_shapes_2/doc/Alpha_shapes_2/PackageDescription.txt b/Alpha_shapes_2/doc/Alpha_shapes_2/PackageDescription.txt index 3203f168390..4d777772e4b 100644 --- a/Alpha_shapes_2/doc/Alpha_shapes_2/PackageDescription.txt +++ b/Alpha_shapes_2/doc/Alpha_shapes_2/PackageDescription.txt @@ -70,12 +70,12 @@ finite number of different \f$ \alpha\f$-shapes and corresponding \cgalCRPSection{Concepts} - `AlphaShapeTraits_2` +- `WeightedAlphaShapeTraits_2` - `AlphaShapeFace_2` - `AlphaShapeVertex_2` \cgalCRPSection{Classes} - `CGAL::Alpha_shape_2
` -- `CGAL::Weighted_alpha_shape_euclidean_traits_2` - `CGAL::Alpha_shape_vertex_base_2` - `CGAL::Alpha_shape_face_base_2` diff --git a/Alpha_shapes_2/include/CGAL/Alpha_shape_euclidean_traits_2.h b/Alpha_shapes_2/include/CGAL/Alpha_shape_euclidean_traits_2.h deleted file mode 100644 index 84399ca3ef4..00000000000 --- a/Alpha_shapes_2/include/CGAL/Alpha_shape_euclidean_traits_2.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 1997 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Tran Kai Frank DA -// Andreas Fabri - -#ifndef CGAL_ALPHA_SHAPE_EUCLIDEAN_TRAITS_H -#define CGAL_ALPHA_SHAPE_EUCLIDEAN_TRAITS_H - -#include - - - -namespace CGAL { - -template < class R > -class Alpha_shape_euclidean_traits_2 : public R -{}; - -} //namespace CGAL - -#endif diff --git a/Alpha_shapes_2/include/CGAL/Weighted_alpha_shape_euclidean_traits_2.h b/Alpha_shapes_2/include/CGAL/Weighted_alpha_shape_euclidean_traits_2.h deleted file mode 100644 index 58847dc2a43..00000000000 --- a/Alpha_shapes_2/include/CGAL/Weighted_alpha_shape_euclidean_traits_2.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 1997 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// Author(s) : Tran Kai Frank DA -// Andreas Fabri - -#ifndef CGAL_WEIGHTED_ALPHA_SHAPE_EUCLIDEAN_TRAITS_2_H -#define CGAL_WEIGHTED_ALPHA_SHAPE_EUCLIDEAN_TRAITS_2_H - -#include - -#define CGAL_DEPRECATED_HEADER "" -#define CGAL_DEPRECATED_MESSAGE_DETAILS \ - "The kernel K can be used directly as traits since weighted points and "\ - "the associated function objects are now part of the concept Kernel." -#include - -namespace CGAL { - -template< class K_ > -class Weighted_alpha_shape_euclidean_traits_2 - : public K_ -{ -public: - Weighted_alpha_shape_euclidean_traits_2() { } - Weighted_alpha_shape_euclidean_traits_2(const K_& k) : K_(k) { } -}; - -} // namespace CGAL - -#endif // CGAL_WEIGHTED_ALPHA_SHAPE_EUCLIDEAN_TRAITS_2_H diff --git a/Alpha_shapes_3/TODO b/Alpha_shapes_3/TODO index 6567995aaed..03c111e94d4 100644 --- a/Alpha_shapes_3/TODO +++ b/Alpha_shapes_3/TODO @@ -12,14 +12,6 @@ when alpha is given as an int. Alpha_shape_3(Dt& dt, bool swap=true, NT alpha = 0, Mode m = REGULARIZED) The triangulation is swapped if swap=true and copied otherwise. -- suppress the traits classes Alpha_shape_euclidean_traits_3.h - and Weighted_alpha_shape_euclidean_traits_3.h - their purpose was to rename the Compute_squared_radius_3 constructor. - The same can be achieved in class Alpha_shapes_3 using the Weighted_tag - of the triangulation - -- same as previous for Alpha_shapes_2 - - test the taking into account of paramater alpha in functions get_alpha_shape_edges get_alpha_shape_facets diff --git a/Alpha_shapes_3/doc/Alpha_shapes_3/Alpha_shapes_3.txt b/Alpha_shapes_3/doc/Alpha_shapes_3/Alpha_shapes_3.txt index 30cc7664e39..2566b5c8bf0 100644 --- a/Alpha_shapes_3/doc/Alpha_shapes_3/Alpha_shapes_3.txt +++ b/Alpha_shapes_3/doc/Alpha_shapes_3/Alpha_shapes_3.txt @@ -219,8 +219,8 @@ in the non-weighted case and `WeightedAlphaShapeTraits_3` in the weighted case. All \cgal kernels are models of both concepts. The triangulation data structure of the triangulation -has to be a model of the concept `TriangulationDataStructure_3`, -and it must be parameterized with vertex and cell classes, which are model of the concepts +has to be a model of the concept `TriangulationDataStructure_3` +whose vertex and cell classes are model of the concepts `AlphaShapeVertex_3` and `AlphaShapeCell_3`. The classes `Alpha_shape_vertex_base_3` and `Alpha_shape_cell_base_3` are models of these concepts and can be used for all type of alpha shapes, @@ -234,8 +234,8 @@ the traits class are described in the concepts `FixedAlphaShapeTraits_3` in the non-weighted case and `FixedWeightedAlphaShapeTraits_3` in the weighted case. All \cgal kernels are models of both concepts. The triangulation data structure of the triangulation -has to be a model of the concept `TriangulationDataStructure_3`, -and it must be parameterized with vertex and cell classes, which are model of the concepts +has to be a model of the concept `TriangulationDataStructure_3` +whose vertex and cell classes are model of the concepts `FixedAlphaShapeVertex_3` and `FixedAlphaShapeCell_3`. The package provides models `Fixed_alpha_shape_vertex_base_3` and `Fixed_alpha_shape_cell_base_3`, respectively. diff --git a/Alpha_shapes_3/include/CGAL/Alpha_shape_euclidean_traits_3.h b/Alpha_shapes_3/include/CGAL/Alpha_shape_euclidean_traits_3.h deleted file mode 100644 index bcfb4c4f46c..00000000000 --- a/Alpha_shapes_3/include/CGAL/Alpha_shape_euclidean_traits_3.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 1997 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// -// Author(s) : Tran Kai Frank DA - -#ifndef CGAL_ALPHA_SHAPE_EUCLIDEAN_TRAITS_3_H -#define CGAL_ALPHA_SHAPE_EUCLIDEAN_TRAITS_3_H - -#include - - -namespace CGAL { - -template -class Alpha_shape_euclidean_traits_3 : public K {}; - - -} //namespace CGAL - -#endif //CGAL_ALPHA_SHAPE_EUCLIDEAN_TRAITS_3_H diff --git a/Alpha_shapes_3/include/CGAL/Weighted_alpha_shape_euclidean_traits_3.h b/Alpha_shapes_3/include/CGAL/Weighted_alpha_shape_euclidean_traits_3.h deleted file mode 100644 index e1fd36c933e..00000000000 --- a/Alpha_shapes_3/include/CGAL/Weighted_alpha_shape_euclidean_traits_3.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) 1997 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// $URL$ -// $Id$ -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// Author(s) : Tran Kai Frank DA - -#ifndef CGAL_WEIGHTED_ALPHA_SHAPE_EUCLIDEAN_TRAITS_3_H -#define CGAL_WEIGHTED_ALPHA_SHAPE_EUCLIDEAN_TRAITS_3_H - -#include - -#define CGAL_DEPRECATED_HEADER "" -#define CGAL_DEPRECATED_MESSAGE_DETAILS \ - "The kernel K can be used directly as traits since weighted points and "\ - "the associated function objects are now part of the concept Kernel." -#include - -namespace CGAL { - -template < class K_ > -class Weighted_alpha_shape_euclidean_traits_3 - : public K_ -{ -public: - Weighted_alpha_shape_euclidean_traits_3() { } - Weighted_alpha_shape_euclidean_traits_3(const K_& k) : K_(k) { } -}; - -} // namespace CGAL - -#endif // CGAL_WEIGHTED_ALPHA_SHAPE_EUCLIDEAN_TRAITS_3_H diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/Apollonius_graph_2.txt b/Apollonius_graph_2/doc/Apollonius_graph_2/Apollonius_graph_2.txt index 34fb0255111..0b2f6aa2082 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/Apollonius_graph_2.txt +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/Apollonius_graph_2.txt @@ -181,7 +181,7 @@ two visible circles. The 2D Apollonius graph class `Apollonius_graph_2` -follows the design of the triangulation package of \cgal. It is +follows the design of the triangulation packages of \cgal. It is parametrized by two arguments:
  • the geometric traits class. It provides the basic diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h index c20ebc9846d..fb82e23c709 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_2.h @@ -4,14 +4,20 @@ namespace CGAL { /*! \ingroup PkgApolloniusGraph2Ref -The class `Apollonius_graph_2` represents the -Apollonius graph. It supports insertions and deletions of sites. -It is templated by two template arguments `Gt`, which -must be a model of `ApolloniusGraphTraits_2`, and `Agds`, -which must be a model of `ApolloniusGraphDataStructure_2`. -The second template argument defaults to -`CGAL::Triangulation_data_structure_2< CGAL::Apollonius_graph_vertex_base_2, CGAL::Triangulation_face_base_2 >`. -\cgalModels `DelaunayGraph_2` +The class `Apollonius_graph_2` represents the Apollonius graph. +It supports insertions and deletions of sites. + +\tparam Gt is the geometric traits class and must be a model of `ApolloniusGraphTraits_2`. + +\tparam Agds is the Apollonius graph data structure and must be a model of `ApolloniusGraphDataStructure_2` +whose vertex and face must be models of `ApolloniusGraphVertexBase_2` and `TriangulationFaceBase_2`, +respectively. +It defaults to: +\code + CGAL::Triangulation_data_structure_2< + CGAL::Apollonius_graph_vertex_base_2, + CGAL::Triangulation_face_base_2 >` +\endcode \cgalHeading{Traversal of the Apollonius Graph} @@ -40,17 +46,11 @@ ag.incident_edges(ag.infinite_vertex()); ag.incident_edges(ag.infinite_vertex(), f); \endcode -\sa `DelaunayGraph_2` -\sa `ApolloniusGraphTraits_2` -\sa `ApolloniusGraphDataStructure_2` -\sa `ApolloniusGraphVertexBase_2` -\sa `TriangulationFaceBase_2` +\cgalModels `DelaunayGraph_2` + \sa `CGAL::Apollonius_graph_traits_2` \sa `CGAL::Apollonius_graph_filtered_traits_2` -\sa `CGAL::Triangulation_data_structure_2` -\sa `CGAL::Apollonius_graph_vertex_base_2` -\sa `CGAL::Triangulation_face_base_2` - +\sa `CGAL::Apollonius_graph_hierarchy_2` */ template< typename Gt, typename Agds > class Apollonius_graph_2 { @@ -92,7 +92,7 @@ typedef Gt::Site_2 Site_2; /// \name Handles And Iterators /// The vertices and faces of the Apollonius graph are accessed -/// through `handles`, `iterators` and `circulators`. The iterators +/// through `handles`, `iterators`, and `circulators`. The iterators /// and circulators are all bidirectional and non-mutable. The /// circulators and iterators are assignable to the corresponding /// handle types, and they are also convertible to the corresponding @@ -261,63 +261,62 @@ operator=(const Apollonius_graph_2& other); /*! Returns a reference to the Apollonius graph traits object. */ -Geom_traits geom_traits(); +const Geom_traits& geom_traits() const; /*! Returns a reference to the underlying data structure. */ -Data_structure data_structure(); +const Data_structure& data_structure() const; /*! Same as `data_structure()`. This method has been added in compliance with the `DelaunayGraph_2` concept. */ -Data_structure tds(); +const Data_structure& tds() const; /*! Returns the dimension of the Apollonius graph. */ -int dimension(); +int dimension() const; /*! Returns the number of finite vertices. */ -size_type number_of_vertices(); +size_type number_of_vertices() const; /*! Returns the number of visible sites. */ -size_type number_of_visible_sites(); +size_type number_of_visible_sites() const; /*! Returns the number of hidden sites. */ -size_type number_of_hidden_sites(); +size_type number_of_hidden_sites() const; /*! Returns the number of faces (both finite and infinite) of the Apollonius graph. */ -size_type number_of_faces(); +size_type number_of_faces() const; /*! Returns a face incident to the `infinite_vertex`. */ -Face_handle infinite_face(); +Face_handle infinite_face() const; /*! Returns the `infinite_vertex`. */ -Vertex_handle -infinite_vertex(); +Vertex_handle infinite_vertex() const; /*! Returns a vertex distinct from the `infinite_vertex`. \pre The number of (visible) vertices in the Apollonius graph must be at least one. */ -Vertex_handle finite_vertex(); +Vertex_handle finite_vertex() const; /// @} @@ -337,63 +336,62 @@ Vertex_handle finite_vertex(); /*! Starts at an arbitrary finite vertex. */ -Finite_vertices_iterator finite_vertices_begin(); +Finite_vertices_iterator finite_vertices_begin() const; /*! Past-the-end iterator. */ -Finite_vertices_iterator finite_vertices_end(); +Finite_vertices_iterator finite_vertices_end() const; /*! Starts at an arbitrary finite edge. */ -Finite_edges_iterator finite_edges_begin(); +Finite_edges_iterator finite_edges_begin() const; /*! Past-the-end iterator. */ -Finite_edges_iterator finite_edges_end(); +Finite_edges_iterator finite_edges_end() const; /*! Starts at an arbitrary finite face. */ -Finite_faces_iterator finite_faces_begin(); +Finite_faces_iterator finite_faces_begin() const; /*! Past-the-end iterator. */ -Finite_faces_iterator finite_faces_end() -const; +Finite_faces_iterator finite_faces_end() const; /*! Starts at an arbitrary vertex. */ -All_vertices_iterator all_vertices_begin(); +All_vertices_iterator all_vertices_begin() const; /*! Past-the-end iterator. */ -All_vertices_iterator all_vertices_end(); +All_vertices_iterator all_vertices_end() const; /*! Starts at an arbitrary edge. */ -All_edges_iterator all_edges_begin(); +All_edges_iterator all_edges_begin() const; /*! Past-the-end iterator. */ -All_edges_iterator all_edges_end(); +All_edges_iterator all_edges_end() const; /*! Starts at an arbitrary face. */ -All_faces_iterator all_faces_begin(); +All_faces_iterator all_faces_begin() const; /*! Past-the-end iterator. */ -All_faces_iterator all_faces_end(); +All_faces_iterator all_faces_end() const; /// @} @@ -407,32 +405,32 @@ All_faces_iterator all_faces_end(); /*! Starts at an arbitrary site. */ -Sites_iterator sites_begin(); +Sites_iterator sites_begin() const; /*! Past-the-end iterator. */ -Sites_iterator sites_end(); +Sites_iterator sites_end() const; /*! Starts at an arbitrary visible site. */ -Visible_sites_iterator visible_sites_begin(); +Visible_sites_iterator visible_sites_begin() const; /*! Past-the-end iterator. */ -Visible_sites_iterator visible_sites_end(); +Visible_sites_iterator visible_sites_end() const; /*! Starts at an arbitrary hidden site. */ -Hidden_sites_iterator hidden_sites_begin(); +Hidden_sites_iterator hidden_sites_begin() const; /*! Past-the-end iterator. */ -Hidden_sites_iterator hidden_sites_end(); +Hidden_sites_iterator hidden_sites_end() const; /// @} @@ -454,39 +452,39 @@ Hidden_sites_iterator hidden_sites_end(); Starts at an arbitrary face incident to `v`. */ -Face_circulator incident_faces(Vertex_handle v); +Face_circulator incident_faces(Vertex_handle v) const; /*! Starts at face `f`. \pre Face `f` is incident to vertex `v`. */ -Face_circulator incident_faces(Vertex_handle v, Face_handle f); +Face_circulator incident_faces(Vertex_handle v, Face_handle f) const; /*! Starts at an arbitrary edge incident to `v`. */ -Edge_circulator incident_edges(Vertex_handle v); +Edge_circulator incident_edges(Vertex_handle v) const; /*! Starts at the first edge of `f` incident to `v`, in counterclockwise order around `v`. \pre Face `f` is incident to vertex `v`. */ -Edge_circulator incident_edges(Vertex_handle v, Face_handle f); +Edge_circulator incident_edges(Vertex_handle v, Face_handle f) const; /*! Starts at an arbitrary vertex incident to `v`. */ -Vertex_circulator incident_vertices(Vertex_handle v); +Vertex_circulator incident_vertices(Vertex_handle v) const; /*! Starts at the first vertex of `f` adjacent to `v` in counterclockwise order around `v`. \pre Face `f` is incident to vertex `v`. */ -Vertex_circulator incident_vertices(Vertex_handle v, Face_handle f); +Vertex_circulator incident_vertices(Vertex_handle v, Face_handle f) const; /// @} @@ -516,7 +514,7 @@ bool is_infinite(Face_handle f, int i) const; `true`, iff edge `e` is infinite. */ bool -is_infinite(Edge e) const; +is_infinite(const Edge& e) const; /*! `true`, iff edge `*ec` is infinite. @@ -544,7 +542,7 @@ site `s` in the Apollonius graph. If `s` is visible then the vertex handle of `s` is returned, otherwise `Vertex_handle(nullptr)` is returned. */ -Vertex_handle insert(Site_2 s); +Vertex_handle insert(const Site_2& s); /*! Inserts `s` in the Apollonius graph using the site @@ -553,8 +551,7 @@ the center of `s`. If `s` is visible then the vertex handle of `s` is returned, otherwise `Vertex_handle(nullptr)` is returned. */ -Vertex_handle insert(Site_2 s, Vertex_handle -vnear); +Vertex_handle insert(const Site_2& s, Vertex_handle vnear); /// @} @@ -581,7 +578,7 @@ arbitrarily and one of the nearest neighbors of `p` is returned. If there are no visible sites in the Apollonius diagram `Vertex_handle(nullptr)` is returned. */ -Vertex_handle nearest_neighbor(Point_2 p); +Vertex_handle nearest_neighbor(const Point_2& p) const; /*! Finds the nearest neighbor of the point @@ -591,8 +588,7 @@ arbitrarily and one of the nearest neighbors of `p` is returned. If there are no visible sites in the Apollonius diagram `Vertex_handle(nullptr)` is returned. */ -Vertex_handle nearest_neighbor(Point_2 p, -Vertex_handle vnear); +Vertex_handle nearest_neighbor(const Point_2& p, Vertex_handle vnear) const; /// @} @@ -645,7 +641,7 @@ the stream `str`. */ template< class Stream > -Stream& draw_primal(Stream& str); +Stream& draw_primal(Stream& str) const; /*! Draws the dual of the @@ -658,7 +654,7 @@ Apollonius graph, i.e., the Apollonius diagram, to the stream */ template < class Stream > -Stream& draw_dual(Stream& str); +Stream& draw_dual(Stream& str) const; /*! Draws the edge @@ -669,7 +665,7 @@ Draws the edge */ template< class Stream > -Stream& draw_primal_edge(Edge e, Stream& str); +Stream& draw_primal_edge(const Edge& e, Stream& str) const; /*! Draws the dual of the @@ -682,7 +678,7 @@ of the Apollonius diagram. */ template< class Stream > -Stream& draw_dual_edge(Edge e, Stream& str); +Stream& draw_dual_edge(const Edge& e, Stream& str) const; /*! Writes the current @@ -690,7 +686,7 @@ state of the Apollonius graph to an output stream. In particular, all visible and hidden sites are written as well as the underlying combinatorial data structure. */ -void file_output(std::ostream& os); +void file_output(std::ostream& os) const; /*! Reads the state of the @@ -701,14 +697,12 @@ void file_input(std::istream& is); /*! Writes the current state of the Apollonius graph to an output stream. */ -std::ostream& operator<<(std::ostream& os, -Apollonius_graph_2 ag); +std::ostream& operator<<(std::ostream& os, const Apollonius_graph_2& ag) const; /*! Reads the state of the Apollonius graph from an input stream. */ -std::istream& operator>>(std::istream& is, -Apollonius_graph_2 ag); +std::istream& operator>>(std::istream& is, const Apollonius_graph_2& ag); /// @} @@ -721,9 +715,9 @@ Checks the validity of the Apollonius graph. If `verbose` is is 0, only the data structure is validated. If `level` is 1, then both the data structure and the Apollonius graph are validated. Negative values of `level` always return true, and -values greater then 1 are equivalent to `level` being 1. +values greater than 1 are equivalent to `level` being 1. */ -bool is_valid(bool verbose = false, int level = 1); +bool is_valid(bool verbose = false, int level = 1) const; /// @} @@ -737,12 +731,11 @@ void clear(); /*! The Apollonius graphs -`other` and `ag` are swapped. `ag`.`swap(other)` should -be preferred to `ag`` = other` or to `ag``(other)` if +`other` and `ag` are swapped. `ag.swap(other)` should +be preferred to `ag = other` or to `ag(other)` if `other` is deleted afterwards. */ -void swap(Apollonius_graph_2 -other); +void swap(Apollonius_graph_2& other); /// @} diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h index 24a11cebc80..778dd9160e1 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_2.h @@ -19,36 +19,34 @@ find the nearest neighbor of \f$ p\f$ as in the we use the nearest neighbor found at level \f$ i+1\f$ to find the nearest neighbor at level \f$ i\f$. This is a variant of the corresponding hierarchy for points found in \cgalCite{d-iirdt-98}. + The class has two template parameters which have essentially the same -meaning as in the `Apollonius_graph_2` class. The first -template parameter must be a model of the -`ApolloniusGraphTraits_2` concept. -The second template parameter must be a model of the -`ApolloniusGraphDataStructure_2` concept. However, the vertex base -class that is to be used in the Apollonius graph data structure must -be a model of the `ApolloniusGraphHierarchyVertexBase_2` concept. -The second template parameter defaults to -`Triangulation_data_structure_2< Apollonius_graph_hierarchy_vertex_base_2< Apollonius_graph_vertex_base_2 >, Triangulation_face_base_2 >`. +meaning as in the `Apollonius_graph_2` class. + +\tparam Gt is the geometric traits class and must be a model of `ApolloniusGraphTraits_2`. + +\tparam Agds is the Apollonius graph data structure and must be a model of `ApolloniusGraphDataStructure_2` +whose vertex and face must be models of `ApolloniusGraphHierarchyVertexBase_2` and `TriangulationFaceBase_2`, respectively. +It defaults to: +\code + CGAL::Triangulation_data_structure_2< + CGAL::Apollonius_graph_hierarchy_vertex_base_2 >, + CGAL::Triangulation_face_base_2 > +\endcode + +\cgalHeading{Heritage} The `Apollonius_graph_hierarchy_2` class derives publicly from the `Apollonius_graph_2` class. The interface is the same with its base class. In the sequel only the methods overridden are documented. -\cgalHeading{Types} - `Apollonius_graph_hierarchy_2` does not introduce other types than those introduced by its base class `Apollonius_graph_2`. -\sa `ApolloniusGraphDataStructure_2` -\sa `ApolloniusGraphTraits_2` -\sa `ApolloniusGraphHierarchyVertexBase_2` \sa `CGAL::Apollonius_graph_2` -\sa `CGAL::Triangulation_data_structure_2` \sa `CGAL::Apollonius_graph_traits_2` \sa `CGAL::Apollonius_graph_filtered_traits_2` -\sa `CGAL::Apollonius_graph_hierarchy_vertex_base_2` - */ template< typename Gt, typename Agds > class Apollonius_graph_hierarchy_2 : public CGAL::Apollonius_graph_2 { @@ -61,8 +59,7 @@ public: Creates an hierarchy of Apollonius graphs using `gt` as geometric traits. */ -Apollonius_graph_hierarchy_2(Gt -gt=Gt()); +Apollonius_graph_hierarchy_2(Gt gt=Gt()); /*! Creates an Apollonius graph hierarchy using @@ -70,17 +67,15 @@ Creates an Apollonius graph hierarchy using range [`first`, `beyond`). */ template< class Input_iterator > -Apollonius_graph_hierarchy_2(Input_iterator -first, Input_iterator beyond, Gt gt=Gt()); +Apollonius_graph_hierarchy_2(Input_iterator first, Input_iterator beyond, Gt gt=Gt()); /*! -Copy constructor. All faces, vertices and inter-level pointers +Copy constructor. All faces, vertices, and inter-level pointers are duplicated. After the construction, `agh` and `other` refer to two different Apollonius graph hierarchies: if `other` is modified, `agh` is not. */ -Apollonius_graph_hierarchy_2 -(Apollonius_graph_hierarchy_2 other); +Apollonius_graph_hierarchy_2(const Apollonius_graph_hierarchy_2& other); /*! Assignment. All faces, vertices and inter-level pointers @@ -112,7 +107,7 @@ site `s` in the Apollonius graph hierarchy. If `s` is visible then the vertex handle of `s` is returned, otherwise `Vertex_handle(nullptr)` is returned. */ -Vertex_handle insert(Site_2 s); +Vertex_handle insert(const Site_2& s); /*! Inserts `s` in the Apollonius graph hierarchy using the @@ -124,8 +119,7 @@ A call to this method is equivalent to `agh.insert(s);` and it has been added for the sake of conformity with the interface of the `Apollonius_graph_2` class. */ -Vertex_handle insert(Site_2 s, Vertex_handle -vnear); +Vertex_handle insert(const Site_2& s, Vertex_handle vnear); /// @} @@ -152,7 +146,7 @@ arbitrarily and one of the nearest neighbors of `p` is returned. If there are no visible sites in the Apollonius diagram `Vertex_handle(nullptr)` is returned. */ -Vertex_handle nearest_neighbor(Point p); +Vertex_handle nearest_neighbor(const Point_2& p) const; /*! Finds the nearest neighbor of the point @@ -163,8 +157,7 @@ A call to this method is equivalent to conformity with the interface of the `Apollonius_graph_2` class. */ -Vertex_handle nearest_neighbor(Point p, -Vertex_handle vnear); +Vertex_handle nearest_neighbor(const Point_2& p, Vertex_handle vnear) const; /// @} @@ -177,7 +170,7 @@ state of the Apollonius graph hierarchy to an output stream. In particular, all visible and hidden sites are written as well as the underlying combinatorial hierarchical data structure. */ -void file_output(std::ostream& os); +void file_output(std::ostream& os) const; /*! Reads the state of the @@ -189,7 +182,7 @@ void file_input(std::istream& is); Writes the current state of the Apollonius graph hierarchy to an output stream. */ -std::ostream& operator<<(std::ostream& os, Apollonius_graph_hierarchy_2 agh); +std::ostream& operator<<(std::ostream& os, Apollonius_graph_hierarchy_2 agh) const; /*! Reads the state of the Apollonius graph hierarchy from an input stream. @@ -209,7 +202,7 @@ is validated, as well as the inter-level pointers. If `level` is 1, then the data structure at all levels is validated, the inter-level pointers are validated and all levels of the Apollonius graph hierarchy are also validated. Negative values of `level` always -return `true`, and values greater then 1 are equivalent to +return `true`, and values greater than 1 are equivalent to `level` being 1. */ bool is_valid(bool verbose = false, int level = 1) const; @@ -227,11 +220,10 @@ void clear(); /*! The Apollonius graph hierarchies `other` and `agh` are -swapped. `agh`.`swap(other)` should be preferred to `agh`` = -other` or to `agh``(other)` if `other` is deleted afterwards. +swapped. `agh.swap(other)` should be preferred to `agh = other` +or to `agh(other)` if `other` is deleted afterwards. */ -void swap(Apollonius_graph_hierarchy_2 -other); +void swap(Apollonius_graph_hierarchy_2& other); /// @} diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_vertex_base_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_vertex_base_2.h index 3d6bc26db21..c09d6255ab5 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_vertex_base_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_hierarchy_vertex_base_2.h @@ -13,10 +13,9 @@ of the `ApolloniusGraphVertexBase_2` concept. \cgalModels `ApolloniusGraphHierarchyVertexBase_2` -\sa `ApolloniusGraphVertexBase_2` -\sa `ApolloniusGraphHierarchyVertexBase_2` \sa `CGAL::Apollonius_graph_vertex_base_2` - +\sa `CGAL::Triangulation_data_structure_2` +\sa `CGAL::Apollonius_graph_hierarchy_2` */ template< typename Agvb > class Apollonius_graph_hierarchy_vertex_base_2 : Agvb { @@ -34,7 +33,7 @@ Apollonius_graph_hierarchy_vertex_base_2(); Constructs a vertex associated with the site `s` and embedded at the center of `s`. */ -Apollonius_graph_hierarchy_vertex_base_2(Site_2 s); +Apollonius_graph_hierarchy_vertex_base_2(const Site_2& s); /*! Constructs a vertex associated with @@ -42,7 +41,7 @@ the site `s`, embedded at the center of `s`, and pointing to the face associated with the face handle `f`. */ -Apollonius_graph_vertex_base_2(Site_2 s, Face_handle f); +Apollonius_graph_hierarchy_vertex_base_2(const Site_2& s, Face_handle f); /// @} diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_traits_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_traits_2.h index ae347df1437..3fe29ef740b 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_traits_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_traits_2.h @@ -22,13 +22,8 @@ The way the predicates are evaluated is discussed in \cgalModels `ApolloniusGraphTraits_2` -\sa `Kernel` -\sa `ApolloniusGraphTraits_2` -\sa `CGAL::Integral_domain_without_division_tag` -\sa `CGAL::Field_with_sqrt_tag` \sa `CGAL::Apollonius_graph_2` \sa `CGAL::Apollonius_graph_filtered_traits_2` - */ template< typename K, typename Method_tag > class Apollonius_graph_traits_2 { @@ -45,14 +40,13 @@ Apollonius_graph_traits_2(); /*! Copy constructor. */ -Apollonius_graph_traits_2(Apollonius_graph_traits_2 other); +Apollonius_graph_traits_2(const Apollonius_graph_traits_2& other); /*! Assignment operator. */ Apollonius_graph_traits_2 -operator=(Apollonius_graph_traits_2 -other); +operator=(const Apollonius_graph_traits_2& other); /// @} diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_vertex_base_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_vertex_base_2.h index a4ba4a49194..ae9eca3dc6e 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_vertex_base_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_graph_vertex_base_2.h @@ -19,13 +19,8 @@ discarded. By default `StoreHidden` is set to `true`. \cgalModels `ApolloniusGraphVertexBase_2` -\sa `ApolloniusGraphVertexBase_2` -\sa `ApolloniusGraphDataStructure_2` -\sa `ApolloniusGraphTraits_2` \sa `CGAL::Triangulation_data_structure_2` -\sa `CGAL::Apollonius_graph_traits_2` -\sa `CGAL::Apollonius_graph_filtered_traits_2` - +\sa `CGAL::Apollonius_graph_hierarchy_vertex_base_2` */ template< typename Gt, typename StoreHidden > class Apollonius_graph_vertex_base_2 { @@ -37,13 +32,13 @@ public: /*! %Default constructor. */ -Apollonius_graph_bertex_base_2(); +Apollonius_graph_vertex_base_2(); /*! Constructs a vertex associated with the site `s` and embedded at the center of `s`. */ -Apollonius_graph_vertex_base_2(Site_2 s); +Apollonius_graph_vertex_base_2(const Site_2& s); /*! Constructs a vertex associated with @@ -51,7 +46,7 @@ the site `s`, embedded at the center of `s`, and pointing to the face associated with the face handle `f`. */ -Apollonius_graph_vertex_base_2(Site_2 s, Face_handle f); +Apollonius_graph_vertex_base_2(const Site_2& s, Face_handle f); /// @} diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_site_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_site_2.h index 03bee290f37..162a6e46259 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_site_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/CGAL/Apollonius_site_2.h @@ -22,12 +22,9 @@ The I/O operators are defined for `iostream`. The information output in the `iostream` is: the point of the Apollonius site and its weight. -\sa `Kernel` -\sa `ApolloniusSite_2` \sa `CGAL::Qt_widget` \sa `CGAL::Apollonius_graph_traits_2` \sa `CGAL::Apollonius_graph_filtered_traits_2` - */ template< typename K > class Apollonius_site_2 { @@ -44,7 +41,7 @@ Apollonius_site_2(Point_2 p=Point_2(), Weight w= Weight(0)); /*! Copy constructor. */ -Apollonius_site_2(Apollonius_site_2 other); +Apollonius_site_2(const Apollonius_site_2& other); /// @} @@ -57,8 +54,7 @@ Apollonius site `s` into the stream `os`. \pre The insert operator must be defined for `Point_2` and `Weight`. \relates Apollonius_site_2 */ -std::ostream& operator<<(std::ostream& os, -const Apollonius_site_2& s); +std::ostream& operator<<(std::ostream& os, const Apollonius_site_2& s) const; /*! Reads an Apollonius site from the stream `is` and assigns it @@ -67,8 +63,7 @@ to `s`. \pre The extract operator must be defined for `Point_2` and `Weight`. \relates Apollonius_site_2 */ -std::istream& operator>>(std::istream& is, -const Apollonius_site_2& s); +std::istream& operator>>(std::istream& is, const Apollonius_site_2& s); /*! Inserts the Apollonius site `s` into the `Qt_widget` stream `w`. @@ -76,7 +71,6 @@ Inserts the Apollonius site `s` into the `Qt_widget` stream `w`. \pre The insert operator must be defined for `K::Circle_2`. \relates Apollonius_site_2 */ -Qt_widget& operator<<(Qt_widget& w, -const Apollonius_site_2& s); +Qt_widget& operator<<(Qt_widget& w, const Apollonius_site_2& s) const; } /* end namespace CGAL */ diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphDataStructure_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphDataStructure_2.h index c2f31f5fa59..8c3209da2e8 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphDataStructure_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphDataStructure_2.h @@ -42,10 +42,10 @@ public: /// @{ /*! -Inserts -a degree two vertex and two faces adjacent to it that have two common -edges. The edge defined by the face handle `f` and the integer -`i` is duplicated. It returns a handle to the vertex created. +inserts a degree two vertex and two faces adjacent to it that have two common edges. + +The edge defined by the face handle `f` and the integer `i` is duplicated. It returns a handle +to the vertex created. */ Vertex_handle insert_degree_2(Face_handle f, int i); diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphHierarchyVertexBase_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphHierarchyVertexBase_2.h index 7de3add41e0..8145923b669 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphHierarchyVertexBase_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphHierarchyVertexBase_2.h @@ -19,17 +19,12 @@ next and previous level graphs. `ApolloniusGraphHierarchyVertexBase_2` does not introduce any types in addition to those of `ApolloniusGraphVertexBase_2`. -\cgalHasModel CGAL::Apollonius_graph_hierarchy_vertex_base_2 > +\cgalHasModel `CGAL::Apollonius_graph_hierarchy_vertex_base_2 >` \sa `ApolloniusGraphDataStructure_2` -\sa `ApolloniusGraphVertexBase_2` \sa `CGAL::Apollonius_graph_hierarchy_2` \sa `CGAL::Triangulation_data_structure_2` -\sa `CGAL::Apollonius_graph_vertex_base_2` -\sa `CGAL::Apollonius_graph_hierarchy_vertex_base_2` - */ - class ApolloniusGraphHierarchyVertexBase_2 { public: @@ -37,8 +32,7 @@ public: /// @{ /*! -Default -constructor. +%Default constructor. */ ApolloniusGraphHierarchyVertexBase_2(); diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphVertexBase_2.h b/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphVertexBase_2.h index 78fad902088..e25279179aa 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphVertexBase_2.h +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/Concepts/ApolloniusGraphVertexBase_2.h @@ -3,8 +3,6 @@ \ingroup PkgApolloniusGraph2Concepts \cgalConcept -\cgalRefines `TriangulationVertexBase_2` - The concept `ApolloniusGraphVertexBase_2` describes the requirements for the vertex base class of the `ApolloniusGraphDataStructure_2` concept. A vertex stores an @@ -12,14 +10,14 @@ Apollonius site and provides access to one of its incident faces through a `Face_handle`. In addition, it maintains a container of sites. The container stores the hidden sites related to the vertex. +\cgalRefines `TriangulationVertexBase_2` + \cgalHasModel `CGAL::Apollonius_graph_vertex_base_2` \sa `ApolloniusGraphDataStructure_2` -\sa `ApolloniusGraphTraits_2` -\sa `CGAL::Apollonius_graph_vertex_base_2` - +\sa `CGAL::Apollonius_graph_2` +\sa `CGAL::Triangulation_data_structure_2` */ - class ApolloniusGraphVertexBase_2 { public: @@ -77,7 +75,7 @@ typedef unspecified_type Hidden_sites_iterator; /// @{ /*! -Default constructor. +%Default constructor. */ ApolloniusGraphVertexBase_2(); diff --git a/Apollonius_graph_2/doc/Apollonius_graph_2/PackageDescription.txt b/Apollonius_graph_2/doc/Apollonius_graph_2/PackageDescription.txt index 706466df36b..f82d98db1ed 100644 --- a/Apollonius_graph_2/doc/Apollonius_graph_2/PackageDescription.txt +++ b/Apollonius_graph_2/doc/Apollonius_graph_2/PackageDescription.txt @@ -43,18 +43,18 @@ aforementioned concepts. \cgalCRPSection{Concepts} - `ApolloniusSite_2` +- `ApolloniusGraphTraits_2` - `ApolloniusGraphDataStructure_2` - `ApolloniusGraphVertexBase_2` -- `ApolloniusGraphTraits_2` - `ApolloniusGraphHierarchyVertexBase_2` \cgalCRPSection{Classes} - `CGAL::Apollonius_graph_2` - `CGAL::Apollonius_site_2` -- `CGAL::Apollonius_graph_vertex_base_2` - `CGAL::Apollonius_graph_traits_2` - `CGAL::Apollonius_graph_filtered_traits_2` +- `CGAL::Apollonius_graph_vertex_base_2` - `CGAL::Apollonius_graph_hierarchy_2` - `CGAL::Apollonius_graph_hierarchy_vertex_base_2` diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt index edbb907114a..ccab1c14e11 100644 --- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt +++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/Arrangement_on_surface_2.txt @@ -73,7 +73,7 @@ parameter must be substituted with a type that defines a set of geometric-object types, such as point and curve, and a set of operations on objects of these types (see Section \ref aos_sec-geom_traits); the `Dcel` parameter must be substituted with a -type that represents a doubly-connected edge list (\sc{Dcel}) data +type that represents a doubly-connected edge list (\dcel) data structure. It defines types of topological object, such as vertices, edges, and faces, and the operations required to maintain the incidence relations among objects of these types (see Section \ref @@ -94,7 +94,7 @@ described above; the `TopologyTraits` parameter must be substituted with a type that deals with the topology of the surface (see Section \ref aos_sec-topol_traits). In particular, it maintains a representation of the arrangement graph embedded in the surface using -a doubly-connected edge list (\sc{Dcel}) data-structure suitable for +a doubly-connected edge list (\dcel) data-structure suitable for the particular topology. Several member functions and nested types defined in the @@ -196,7 +196,7 @@ embedding surface plays a significant role. In Section \ref arr_ssecnotif we review the notification mechanism that allows external classes to keep track of the changes that an arrangement instance goes through. Section \ref arr_ssecex_dcel explains how to -extend the \sc{Dcel} records, to store extra data with them, and to +extend the \dcel records, to store extra data with them, and to efficiently update this data. In Section \ref arr_ssecoverlay we introduce the fundamental operation of overlaying two arrangements. Section \ref arr_ssecarr_with_hist describes a class-template that @@ -215,7 +215,7 @@ We start with a formal definition of two-dimensional arrangements, and proceed with an introduction to the data structure used to represent the incidence relations among features of two-dimensional arrangements, namely, the doubly-connected edge list, or -\sc{Dcel} for short. In Section \ref aos_ssec-basic-arr_class we +\dcel for short. In Section \ref aos_ssec-basic-arr_class we describe a central component in the \ref PkgArrangementOnSurface2 package, namely, the `Arrangement_2` class-template, which can be used to represent arrangements in the plane. @@ -267,19 +267,19 @@ C'')\f$. There are possibly more vertices in \f$\cal A(\cal C'')\f$ than in \f$\cal A(\cal C)\f$---the vertices where curves were cut into \f$x\f$-monotone (non-intersecting) pieces; accordingly there may also be more edges in \f$\cal A(\cal C'')\f$. This graph can be represented -using a doubly-connected edge list data-structure -(\sc{Dcel}), which consists of containers of vertices, edges and faces -and maintains the incidence relations among these cells. It is one of -a family of combinatorial data structures called halfedge data -structures (\sc{Hds}), which are edge-centered data structures -capable of maintaining incidence relations among cells of, for -example, planar subdivisions, polyhedra, or other orientable, -two-dimensional surfaces embedded in space of an arbitrary -dimension. Geometric interpretation is added by classes built on top -of the halfedge data structure. In our implementation and in the reset -of this chapter we use the arrangement \f$\cal A(\cal C')\f$, which is -equal to \f$\cal A(\cal C'')\f$. Note that \f$\cal A(\cal C) = \cal -A(\cal C')\f$ iff \f$\cal C' == \cal C''\f$. +using a doubly-connected edge list data-structure (\dcel), +which consists of containers of vertices, edges and faces and +maintains the incidence relations among these cells. It is one of a +family of combinatorial data structures called halfedge data +structures (Hds), which are +edge-centered data structures capable of maintaining incidence +relations among cells of, for example, planar subdivisions, polyhedra, +or other orientable, two-dimensional surfaces embedded in space of an +arbitrary dimension. Geometric interpretation is added by classes +built on top of the halfedge data structure. In our implementation and +in the reset of this chapter we use the arrangement \f$\cal A(\cal +C')\f$, which is equal to \f$\cal A(\cal C'')\f$. Note that \f$\cal +A(\cal C) = \cal A(\cal C')\f$ iff \f$\cal C' == \cal C''\f$. \cgalAdvancedBegin @@ -300,7 +300,7 @@ details. \cgalAdvancedEnd -The \sc{Dcel} data-structure represents each edge using a pair of +The \dcel data-structure represents each edge using a pair of directed halfedges, one going from the \f$xy\f$-lexicographically smaller (left) endpoint of the curve towards the \f$xy\f$-lexicographically larger (right) endpoint, and @@ -317,7 +317,7 @@ incident halfedges.) An edge of an arrangement is a maximal portion of a curve between two vertices of the arrangement. Each edge is represented in -the \sc{Dcel} by a pair of twin halfedges. Each halfedge \f$e\f$ +the \dcel by a pair of twin halfedges. Each halfedge \f$e\f$ stores a pointer to its incident face, which is the face lying to its left. Moreover, every halfedge is followed by another halfedge sharing the same incident face, such that the target vertex of the @@ -342,13 +342,13 @@ it may contain several faces. Every face can have several inner CCBs in its interior, or may not contain inner CCBs at all. In addition, every face may contain isolated vertices in its interior. See \cgalFigureRef{aos_fig-arr_segs} for an illustration of the various -\sc{Dcel} features. For more details on the \sc{Dcel} data structure +\dcel features. For more details on the \dcel data structure see \cgalCite{bkos-cgaa-00} Chapter 2. \cgalFigureBegin{aos_fig-arr_segs,arr_segs.png} An arrangement of interior-disjoint line segments with some of the -\sc{Dcel} records that represent it. The unbounded face \f$ f_0\f$ has +\dcel records that represent it. The unbounded face \f$ f_0\f$ has a single connected component that forms a hole inside it, and this hole is comprised of several faces. The halfedge \f$ e\f$ is directed from its source vertex \f$ v_1\f$ to its target vertex \f$ @@ -417,7 +417,7 @@ the `Arrangement_2` class template; their description follows. substituted with `Arr_default_dcel` by default, and we use this default value in this and in the following three sections. However, in many applications it is necessary to - extend the \sc{Dcel} features. This is done by substituting the + extend the \dcel features. This is done by substituting the `Dcel` parameter with a different type; see Section \ref arr_ssecex_dcel for further explanations and examples.
@@ -505,7 +505,7 @@ The simplest and most fundamental arrangement operations are the various traversal methods, which allow users to systematically go over the relevant features of the arrangement at hand. -As mentioned above, the arrangement is represented as a \sc{Dcel}, +As mentioned above, the arrangement is represented as a \dcel, which stores three containers of vertices, halfedges and faces; thus, the `Arrangement_2` class template supplies iterator types for these containers, respectively. For example, if `arr` is an `Arrangement_2` @@ -841,7 +841,7 @@ examples. Illustrations of the various specialized insertion procedures. The inserted \f$x\f$-monotone curve is drawn as a dashed line, surrounded by two solid arrows that represent the pair of twin halfedges added to -the \sc{Dcel}. Existing vertices are shown as black discs, while new +the \dcel. Existing vertices are shown as black discs, while new vertices are shown as light discs. Existing halfedges that are affected by the insertion operations are drawn as dashed arrows. (a) Inserting a curve as a new hole inside the face \f$f\f$. (b) @@ -1402,9 +1402,9 @@ vary according to the user choice.} for answering queries: of landmark points, the location of which in the arrangement is known. It employs the landmark strategy. Given a query point, it uses a nearest-neighbor - search-structure (a \sc{Kd}-tree is used by default) to find the - nearest landmark, and then traverses the straight-line segment - connecting this landmark to the query point. + search-structure (a Kd-tree is used by + default) to find the nearest landmark, and then traverses the + straight-line segment connecting this landmark to the query point. There are various ways to select the landmark set in the arrangement. The selection is governed by the `Generator` @@ -1476,23 +1476,24 @@ trapezoidal map RIC strategy. In addition, although both resulting data structures are asymptotically linear in size, the actual amount of memory consumed by the landmark algorithm is typically smaller than to the amount used by the trapezoidal map RIC algorithm, due to the -space-efficient \sc{Kd}-tree used by the landmark algorithm as the -nearest-neighbor search-structure. The trapezoidal map RIC algorithm -has expected logarithmic query time, while the query time for the -landmark algorithm may be as large as linear. In practice however, the -query times of both strategies are competitive. For a detailed -experimental comparison see \cgalCite{cgal:hh-eplca-05}. +space-efficient Kd-tree used by the +landmark algorithm as the nearest-neighbor search-structure. The +trapezoidal map RIC algorithm has expected logarithmic query time, +while the query time for the landmark algorithm may be as large as +linear. In practice however, the query times of both strategies are +competitive. For a detailed experimental comparison see +\cgalCite{cgal:hh-eplca-05}. Updating the auxiliary data structures of the trapezoidal map RIC algorithm is done very efficiently. On the other hand, updating the nearest-neighbor search-structure of the landmark algorithm may consume significant time when the arrangement changes frequently, -especially when a \sc{Kd}-tree is used, as it must be rebuilt each -time the arrangement changes. It is therefore recommended that the -`Arr_landmarks_point_location` class template be used when the -application frequently issues point-location queries on an arrangement -that only seldom changes. If the arrangement is more dynamic and is -frequently going through changes, the +especially when a Kd-tree is used, as it +must be rebuilt each time the arrangement changes. It is therefore +recommended that the `Arr_landmarks_point_location` class template be +used when the application frequently issues point-location queries on +an arrangement that only seldom changes. If the arrangement is more +dynamic and is frequently going through changes, the `Arr_trapezoid_ric_point_location` class template should be the selected point-location strategy. @@ -2013,7 +2014,7 @@ so it must be construct from scratch. (ii) The given arrangement `arr` is not empty. In the first case, we sweep over the input curves, compute their -intersection points, and construct the \sc{Dcel} that represents their +intersection points, and construct the \dcel that represents their arrangement. This process is performed in \f$O\left((n + k)\log n\right)\f$ time, where \f$k\f$ is the total number of intersection points. The running time is asymptotically better than the time needed @@ -2301,7 +2302,7 @@ introduced. \cgalFigureBegin{aos_fig-unb_dcel,unb_dcel.png} -A \sc{Dcel} representing an arrangement of four lines. Halfedges are +A \dcel representing an arrangement of four lines. Halfedges are drawn as thin arrows. The vertices \f$v_1, \ldots, v_8\f$ lie at infinity, and are not associated with valid points. The halfedges that connect them are fictitious, and are not associated with concrete @@ -2314,7 +2315,7 @@ represent the four corners of the imaginary bounding rectangle. Instead of an explicit approach, we use an implicit bounding rectangle -embedded in the \sc{Dcel} structure. \cgalFigureRef{aos_fig-unb_dcel} +embedded in the \dcel structure. \cgalFigureRef{aos_fig-unb_dcel} shows the arrangement of four lines that subdivide the plane into eight unbounded faces and two bounded ones. Notice that in this case portions of the the unbounded faces now have outer boundaries (those @@ -2861,10 +2862,10 @@ one pinch point, is modeled by identifying the vertical and identifying the horizontal sides and, in addition, contracting one of the pairs. However, the croissant is excluded by our definitions. All surfaces supported by our framework are locally homeomorphic to a -disk, and hence an \sc{Dcel} data-structure suffices for representing +disk, and hence an \dcel data-structure suffices for representing arrangements on these surfaces. The croissant is, at the pinch point, not locally homeomorphic to a disk, and hence a more general -cell-tuple data structure than an \sc{Dcel} would be needed. +cell-tuple data structure than an \dcel would be needed. A curve \f$\gamma\f$ is a continuous function \f$\gamma: I \rightarrow \Phi\f$, where \f$I\f$ is an open, half-open, or closed interval with @@ -3173,12 +3174,13 @@ class, thereby extending it. A hierarchy of related concepts can be viewed as a directed acyclic graph, where a node of the graph represents a concept and an arc -represents a refinement relation. An arc directed from concept \sc{A} -to concept \sc{B} indicates that concept \sc{B} refines concept -\sc{A}. A rather large direccted acyclic graph is required to capture -the entire hierarchy of the geometry traits-class concepts. In the -following sections we review individual clusters of the graph and -describe the relations between them. +represents a refinement relation. An arc directed from concept A to concept B +indicates that concept B refines concept +A. A rather large direccted acyclic graph +is required to capture the entire hierarchy of the geometry +traits-class concepts. In the following sections we review individual +clusters of the graph and describe the relations between them. \cgalFigureRef{aos_fig-central_concept_cluster} depicts the central cluster. @@ -3555,7 +3557,7 @@ class that models the combined concept \cgalFigureRef{aos_fig-open_concept_hierarchy} can handle curves that are open in any direction. Recall that an arrangement that supports unbounded \f$x\f$-monotone curves maintains an implicit bounding -rectangle in the \sc{Dcel} structure; see Section \ref +rectangle in the \dcel structure; see Section \ref aos_sec-unbounded. If some curves inserted into an arrangement object are expected to be unbounded; namely, there exists \f$d \in \{0,1\}\f$ such that \f$\lim_{t \rightarrow d}x(t) = \pm\infty\f$ or \f$\lim_{t @@ -4648,9 +4650,9 @@ these types, solving quadratic equations, and extracting the real roots of polynomials with integer coefficients. The use of the `CORE_algebraic_number_traits` class, which is included in the arrangement package, is highly recommended. The traits class-template -relies on the multi-precision number types implemented in the -\sc{Core} library and performs exact computations on the number types -it defines. +relies on the multi-precision number types implemented in the Core library and performs exact computations on +the number types it defines. @@ -4658,10 +4660,11 @@ The instantiation of the conic traits class-template is slightly more complicated than the instantiation of the traits classes you have encountered so far. This instantiation is exemplified in the header file `arr_conics.h`. Note how we first define the rational and -algebraic kernels using the number types given by the \sc{Core} number -type traits-class, then use them to define the conic traits -class-template. Also note the types defined by the rational kernels, -which we need for conveniently constructing conic arcs. +algebraic kernels using the number types given by the Core number type traits-class, then use them to +define the conic traits class-template. Also note the types defined by +the rational kernels, which we need for conveniently constructing +conic arcs. The `Arr_conic_traits_2` models the `ArrangementTraits_2` and `ArrangementLandmarkTraits_2` concepts. Its \link @@ -5351,7 +5354,7 @@ to the geometric objects (curves and to points). The data is automatically manipulated by the decorators and distributed to the constructed geometric entities. Additional information can alternatively be maintained by extending the vertex, halfedge, or face -types provided by the \sc{Dcel} class used by the arrangement; see +types provided by the \dcel class used by the arrangement; see Section \ref arr_ssecex_dcel for details. In many cases, however, it is convenient to attach the data to the curve itself, exploiting the automatic proliferation of the additional data fields from each curve @@ -5526,7 +5529,7 @@ handle these topological entities, used by the `Arrangement_on_surface_2` class template and by the peripheral modules. Every topology traits class must model the basic concept `ArrangementBasicTopologyTraits`. A model -of this basic concept holds the (\sc{Dcel}) data structure used to +of this basic concept holds the (\dcel) data structure used to represent the arrangement cells (i.e., vertices, edges, and facets) and the incidence relations between them. At this point we do not expose the concepts that refine the basic concept. The package @@ -5714,7 +5717,7 @@ of \f$e_v\f$. \cgalExample{Arrangement_on_surface_2/observer.cpp} -Observers are especially useful when the \sc{Dcel} records are +Observers are especially useful when the \dcel records are extended and store additional data-fields, since they help update this data stored in these fields, as the following sections reveal. @@ -5732,21 +5735,21 @@ Arrangement_on_surface_2::X_monotone_curve_2 class. Extending the geometric traits-class types by using a traits-class decorator, as explained in Section \ref arr_ssecmeta_tr, might be a sufficient solution for some applications. However, the -\sc{Dcel} faces are not associated with any geometric object, so -traits-class decorators cannot help here. Extending the \sc{Dcel} face +\dcel faces are not associated with any geometric object, so +traits-class decorators cannot help here. Extending the \dcel face records comes in handy is such cases. As a matter of fact, it is -possible to conveniently extend all \sc{Dcel} records (namely +possible to conveniently extend all \dcel records (namely vertices, halfedges, and faces), which is advantageous for some applications. -All examples presented so far use the default \sc{Dcel}; namely, they +All examples presented so far use the default \dcel; namely, they employ the `Arr_default_dcel` instance. This is done implicitly, as an instance of this class template serves as the default parameter for the `Arrangement_2` class template; see Section -\ref aos_ssec-basic-arr_class. The default \sc{Dcel} class associates +\ref aos_ssec-basic-arr_class. The default \dcel class associates points with vertices and \f$x\f$-monotone curves with halfedges, but nothing more. In this section we show how to use alternative -\sc{Dcel} types to extend the desired \sc{Dcel} records. +\dcel types to extend the desired \dcel records. \subsubsection arr_sssecex_dcel_face Extending the DCEL Faces @@ -5754,8 +5757,8 @@ nothing more. In this section we show how to use alternative The `Arr_face_extended_dcel` class-template is used to associate auxiliary data field of type `FaceData` to each face -record in the \sc{Dcel}. When the `Arrangement_2` class -template is instantiated, substituting the \sc{Dcel} parameter with an +record in the \dcel. When the `Arrangement_2` class +template is instantiated, substituting the \dcel parameter with an instance of this class template, the interface of the nested `Face` type is extended with the access function `data()` and with the modifier `set_data()`. Using these extra functions it is @@ -5807,15 +5810,15 @@ crucial. Perhaps less common, but also important to satisfy, is the need to extend the vertex and halfedge records as well. The `Arr_extended_dcel` class-template is used to associate auxiliary data fields of types -`VertexData`, `HalfedgeData`, and `FaceData` with \sc{Dcel} vertex, +`VertexData`, `HalfedgeData`, and `FaceData` with \dcel vertex, halfedge, and face record types, respectively. When the `Arrangement_2` class template is instantiated, -substituting the `Dcel` parameter with an instance of this \sc{Dcel} +substituting the `Dcel` parameter with an instance of this \dcel class-template, the interfaces of the nested types Vertex, Halfedge, and Face are extended with the access function `data()` and with the modifier `set_data()`. -The next example shows how to use a \sc{Dcel} with extended vertex, +The next example shows how to use a \dcel with extended vertex, halfedge, and face records. In this example each vertex is associated with a color, which is either blue, red, or white, depending on whether the vertex is isolated, represents a segment endpoint, or represents @@ -5840,19 +5843,19 @@ arrangement object. \cgalAdvancedBegin -The various \sc{Dcel} classes presented in this section are well +The various \dcel classes presented in this section are well suited for most applications based on the \ref PkgArrangementOnSurface2 package. They are all defined using helper -constructs, and in particular the base \sc{Dcel} class-template +constructs, and in particular the base \dcel class-template `Arr_dcel_base}`. However, there are cases where special -requirements, not addressed by these \sc{Dcel} classes, are needed. -In such cases you may explicitly extend the base \sc{Dcel} +requirements, not addressed by these \dcel classes, are needed. +In such cases you may explicitly extend the base \dcel class-template, as described in the next paragraph, or implement your -own \sc{Dcel} class from scratch and use the resulting \sc{Dcel} to +own \dcel class from scratch and use the resulting \dcel to instantiate the `Arrangement_2` class template. In any case such a class must model the concept `ArrangementDcel` or its refinement `ArrangementDcelWithRebind`. The latter requires a `rebind` struct -template, which implements a policy-clone idiom. Here, the \sc{Dcel} +template, which implements a policy-clone idiom. Here, the \dcel class is the policy class and the `rebind` member template struct is used to pass a different traits type parameter to the policy class template. @@ -5878,7 +5881,7 @@ due to compiler padding.\cgalFootnote{Compilers add pad bytes into user-defined constructs to comply with alignment restrictions imposed by target microprocessors.} Moreover, the code may look cumbersome. -The extended \sc{Dcel} class that addresses the problem raised above +The extended \dcel class that addresses the problem raised above is listed below. Here, each feature type is explicitly extended with two strings, namely, `name` and `type`, eliminating the data constructs. @@ -5953,7 +5956,7 @@ efficient process. For example, monochromatic intersections are not computed. The plane-sweep visitor that concretizes the overlay operation needs -to construct a \sc{Dcel} that properly represents the overlay of two +to construct a \dcel that properly represents the overlay of two input arrangements. A face in the overlay arrangement corresponds to overlapping regions of the blue and red faces. An edge in the overlay arrangement is due to a blue edge, a red edge, or an overlap of two @@ -5977,10 +5980,10 @@ same geometry-traits class. The `overlay()` function template is suitable for arrangements that do not store any additional data with their -\sc{Dcel} records; namely, arrangements defined using an instance of -the default \sc{Dcel} class-template `Arr_default_dcel`. Typically, +\dcel records; namely, arrangements defined using an instance of +the default \dcel class-template `Arr_default_dcel`. Typically, the overlay arrangement in this case does not store extra data with -its \sc{Dcel} records as well (or if it does, the additional +its \dcel records as well (or if it does, the additional data-fields cannot be computed by the overlay operation). The overlay arrangement is equivalent to the arrangement induced by all curves of `arr_r` and `arr_b`. Indeed, it is possible to obtain the same result @@ -6022,7 +6025,7 @@ We distinguish between (i) an overlay of two arrangements that store additional data-fields only with their faces e.g., the geographic-map example given at the beginning of this section) and (ii) an overlay of two arrangements that store additional data fields with all their -\sc{Dcel} records (or at least not only with their faces). The +\dcel records (or at least not only with their faces). The arrangement that results from overlaying two face-extended arrangements typically also stores additional data-fields with its faces. The types of such arrangements, for example, could be instances @@ -6033,8 +6036,8 @@ arr_sssecex_dcel_face). The data field that is attached to an overlay face can be computed from the data fields of the two faces (in `arr_r` and `arr_b`) that induce the overlay face. Similarly, the arrangement that results from overlaying two arrangements that store additional -data fields with all their \sc{Dcel} records typically also stores -additional data-fields with all its \sc{Dcel} records. The types of +data fields with all their \dcel records typically also stores +additional data-fields with all its \dcel records. The types of such arrangements, for example, could be instances of the `Arrangement_2` class template, where the `Dcel` parameters are substituted with instances of the `Arr_extended_dcel` @@ -6043,7 +6046,7 @@ attached to an overlay feature can be computed from the data fields of the two features (in `arr_r` and `arr_b`) that induce the overlay feature. -As mentioned in the previous paragraph, if any of the \sc{Dcel} +As mentioned in the previous paragraph, if any of the \dcel records of your arrangements are extended, you can pass a fourth argument to the `overlay()` call, also referred to as the overlay traits, to control the generation of the extended data in the @@ -6061,8 +6064,8 @@ overlay faces. The following example shows how to compute the intersection of two polygons using the `overlay()` function template. It uses a -face-extended \sc{Dcel} type to instantiate the arrangement -classes. Each face of the the \sc{Dcel} is extended with a Boolean +face-extended \dcel type to instantiate the arrangement +classes. Each face of the the \dcel is extended with a Boolean flag. A polygon is represented as a marked arrangement face (whose flag is set). The example uses an instance of the `Arr_face_overlay_traits` class @@ -6105,8 +6108,8 @@ into strings to produce the final labels. \cgalExample{Arrangement_on_surface_2/overlay_unbounded.cpp} If the red and blue arrangements store additional data-fields with all -their \sc{dcel} records, and the data associated with the overlay -\sc{dcel} features should be computed from the red and blue \sc{dcel} +their \dcel records, and the data associated with the overlay +\dcel features should be computed from the red and blue \dcel features that induce it, then an appropriate overlay-traits argument must be passed to the `overlay()` call. The overlay-traits type models the `OverlayTraits` concept, which requires the provision of ten @@ -6249,7 +6252,7 @@ arbitrary two-dimensional curves, you end up with a collection \f$\cal C''\f$ of \f$x\f$-monotone subcurves of \f$\cal C\f$ that are pairwise disjoint in their interior; see Section \ref aos_sec-intro. These subcurves are associated with the arrangement edges (more precisely, -with pairs of \sc{Dcel} halfedges). The connection between the +with pairs of \dcel halfedges). The connection between the originating input curves and the arrangement edges is lost during the construction process. This loss might be acceptable for some applications. However, in many practical cases it is important to @@ -6272,8 +6275,8 @@ its subdivision into \link ArrangementBasicTraits_2::X_monotone_curve_2 `X_monotone_curve_2`\endlink objects, among the others. The `Dcel` parameter must be substituted with a model of the `ArrangementDcel` -concept. You can use either the default \sc{Dcel} class or an extended -\sc{Dcel} class (see Section \ref arr_ssecex_dcel) based on your +concept. You can use either the default \dcel class or an extended +\dcel class (see Section \ref arr_ssecex_dcel) based on your needs. An arrangement that support the cross-mapping mentioned above is referred to as an arrangement with history. In the following we use the `Arrangement_with_history_2<>` class template to demonstrate @@ -6354,7 +6357,7 @@ arrangement stores a consolidated container of input curves, and automatically preserves the cross-mapping between the arrangement edges and the consolidated curve-set. You may also employ an overlay-traits class to maintain any type of auxiliary data stored -with the \sc{Dcel} cells; see Section \ref arr_ssecoverlay. +with the \dcel cells; see Section \ref arr_ssecoverlay. \subsubsection arr_sssecmodif_traverse Modifying an Arrangement with History @@ -6534,7 +6537,7 @@ the arrangement features. Thus, they are ideal for arrangements instantiated using the `Arr_default_dcel` class. However, as explained in Section \ref arr_ssecex_dcel, one can easily extend the arrangement faces by using the `Arr_face_extended_dcel` -template, or extend all \sc{Dcel} records by using the `Arr_extended_dcel` +template, or extend all \dcel records by using the `Arr_extended_dcel` template. In such cases, it might be crucial that the auxiliary data fields are written to the file and read from there. @@ -6551,13 +6554,13 @@ auxiliary data that may be associated with the arrangement features. This is the default formatter used by the arrangement inserter and the arrangement extractor, as defined above.
  • `Arr_face_extended_text_formatter` operates on -arrangements whose \sc{Dcel} representation is based on the +arrangements whose \dcel representation is based on the `Arr_face_extended_dcel` class (see Section \ref arr_sssecex_dcel_face). It supports reading and writing the auxiliary data objects stored with the arrangement faces provided that the `FaceData` class supports an inserter and an extractor.
  • `Arr_extended_dcel_text_formatter` operates on -arrangements whose \sc{Dcel} representation is based on the +arrangements whose \dcel representation is based on the `Arr_extended_dcel` class (see Section \ref arr_sssecex_dcel_all). It supports reading and writing the auxiliary data objects stored with the arrangement vertices, edges @@ -6625,37 +6628,40 @@ and defines a simple textual input/output format. \section aos_sec-bgl Adapting to Boost Graphs -\sc{Boost}\cgalFootnote{See also \sc{Boost}'s homepage at: -www.boost.org.} is a collection of portable \cpp libraries -that extend the \cpp Standard Library. The \sc{Boost} Graph Library -(\sc{bgl}), which one of the libraries in the collection, offers an -extensive set of generic graph algorithms parameterized through -templates. As our arrangements are embedded as planar graphs, it is -only natural to extend the underlying data structure with the -interface that the <\sc{bgl} expects, and gain the ability to perform -the operations that the \sc{bgl} supports, such as shortest-path +Boost\cgalFootnote{See also Boost's homepage at: www.boost.org.} +is a collection of portable \cpp libraries that extend the \cpp +Standard Library. The Boost Graph Library +(bgl), which one of the libraries in the +collection, offers an extensive set of generic graph algorithms +parameterized through templates. As our arrangements are embedded as +planar graphs, it is only natural to extend the underlying data +structure with the interface that the bgl +expects, and gain the ability to perform the operations that the bgl supports, such as shortest-path computation. This section describes how to apply the graph algorithms -implemented in the \sc{bgl} to `Arrangement_2` instances. +implemented in the bgl to `Arrangement_2` +instances. -An instance of `Arrangement_2` is adapted to a \sc{Boost} graph -through the provision of a set of free functions that operate on the -arrangement features and conform with the relevant BGL -concepts. Besides the straightforward adaptation, which associates a -vertex with each \sc{Dcel} vertex and an edge with each \sc{Dcel} -halfedge, the package also offer a dual adaptor, which -associates a graph vertex with each \sc{Dcel} face, such that two -vertices are connected, iff there is a \sc{Dcel} halfedge that +An instance of `Arrangement_2` is adapted to a Boost graph through the provision of a set of +free functions that operate on the arrangement features and conform +with the relevant BGL concepts. Besides the straightforward +adaptation, which associates a vertex with each \dcel vertex and an +edge with each \dcel halfedge, the package also offer a dual +adaptor, which associates a graph vertex with each \dcel face, such +that two vertices are connected, iff there is a \dcel halfedge that connects the two corresponding faces. \subsection arr_ssecbgl_primal The Primal Arrangement Representation -Arrangement instances are adapted to \sc{Boost} graphs by specializing -the \link BGLArgtGT `boost:graph_traits` \endlink template for -`Arrangement_2` instances. The graph-traits states the graph concepts -that the arrangement class models (see below) and defines the types -required by these concepts. +Arrangement instances are adapted to Boost +graphs by specializing the \link BGLArgtGT `boost:graph_traits` +\endlink template for `Arrangement_2` instances. The graph-traits +states the graph concepts that the arrangement class models (see +below) and defines the types required by these concepts. In this specialization the `Arrangement_2` vertices correspond to the graph vertices, where two vertices are adjacent if there is at least @@ -6668,13 +6674,13 @@ to be directed as well. Moreover, as several interior-disjoint \f$x\f$-monotone curves (say circular arcs) may share two common endpoints, inducing an arrangement with two vertices that are connected with several edges, we allow parallel edges in our -\sc{Boost} graph. +Boost graph. Given an `Arrangement_2` instance, we can efficiently traverse its vertices and halfedges. Thus, the arrangement graph is a model of the -concepts `VertexListGraph` and `EdgeListGraph` introduced by the -\sc{bgl}. At the same time, we use an iterator adapter of the -circulator over the halfedges incident to a vertex +concepts `VertexListGraph` and `EdgeListGraph` introduced by the bgl. At the same time, we use an iterator +adapter of the circulator over the halfedges incident to a vertex (`Halfedge_around_vertex_circulator` - see Section \ref arr_sssectr_vertex), so it is possible to go over the ingoing and outgoing edges of a vertex in linear time. Thus, our arrangement graph @@ -6685,24 +6691,26 @@ edges). It is important to notice that the vertex descriptors we use are \link Arrangement_2 Vertex_handle `Vertex_handle`\endlink objects and not vertex indices. However, in order to gain more efficiency -in most \sc{bgl} algorithms, it is better to have them indexed \f$0, -1, \ldots, (n-1)\f$, where \f$n\f$ is the number of vertices. We -therefore introduce the `Arr_vertex_index_map` -class-template, which maintains a mapping of vertex handles to -indices, as required by the \sc{bgl}. An instance of this class must -be attached to a valid arrangement vertex when it is created. It uses -the notification mechanism (see Section \ref arr_ssecnotif) to +in most bgl algorithms, it is better to +have them indexed \f$0, 1, \ldots, (n-1)\f$, where \f$n\f$ is the +number of vertices. We therefore introduce the +`Arr_vertex_index_map` class-template, which maintains a +mapping of vertex handles to indices, as required by the bgl. An instance of this class must be attached +to a valid arrangement vertex when it is created. It uses the +notification mechanism (see Section \ref arr_ssecnotif) to automatically maintain the mapping of vertices to indices, even when new vertices are inserted into the arrangement or existing vertices are removed. -In most algorithms provided by the \sc{bgl}, the output is given by -property maps, such that each map entry corresponds to a -vertex. For example, when we compute the shortest paths from a given -source vertex \f$s\f$ to all other vertices we can obtain a map of -distances and a map of predecessors - namely for each \f$v\f$ vertex -we have its distance from \f$s\f$ and a descriptor of the vertex that -precedes \f$v\f$ in a shortest path from \f$s\f$. +In most algorithms provided by the bgl, +the output is given by property maps, such that each map +entry corresponds to a vertex. For example, when we compute the +shortest paths from a given source vertex \f$s\f$ to all other +vertices we can obtain a map of distances and a map of predecessors - +namely for each \f$v\f$ vertex we have its distance from \f$s\f$ and a +descriptor of the vertex that precedes \f$v\f$ in a shortest path from +\f$s\f$. If the vertex descriptors are simply indices, boost supplies tools to easily represent property maps using vectors. The @@ -6714,8 +6722,8 @@ mapping from \link Arrangement_on_surface_2::Vertex_handle however, that unlike the `Arr_vertex_index_map` class template, the vertex property-map class is not kept synchronized with the number of vertices in the arrangement, so it should not be reused in calls to -\sc{bgl} functions in case the arrangement is modified in between -these calls. +bgl functions in case the arrangement is +modified in between these calls. The first example of this section demonstrates the application of Dijkstra's shortest path algorithm to compute the shortest-path length @@ -6724,8 +6732,9 @@ other vertices. The length of a path is defined as the sum of squared Euclidean lengths of its segments. It uses an instance of the functor template `Edge_length}` to compute the squared Euclidean length of the linear curve associated with a given halfedge of the -arrangement. The functor implements a \sc{Boost} property-map that -attaches square lengths to edges; when the \sc{bgl} algorithm queries +arrangement. The functor implements a Boost property-map that attaches square lengths +to edges; when the bgl algorithm queries the property map for a squared length of an edge the property map computes and returns it. The functor template is defined in the header file `Edge_length.h`. @@ -6765,15 +6774,16 @@ An arrangement of seven line segments, as constructed by In the following example we construct an arrangement of seven line segments, as shown in \cgalFigureRef{aos_fig-bgl_primal_adapter}. -Then, it uses the \sc{bgl} generic implementation of Dijkstra's -shortest-paths algorithm to compute the sum of squared distances to -all vertices from the lexicographically smallest vertex \f$v_0\f$ in -the arrangement. Note the usage of the `Arr_vertex_property_map` class -template in the call to `boost::dijkstra_shortest_paths()` and in the -definition of the distance property-map. We instantiate a property map -that attaches a number of type `Number_type` (which is a type of -unlimited precision) to each vertex. The number represents the sum of -squared distances of the vertex from $v_0$. +Then, it uses the bgl generic +implementation of Dijkstra's shortest-paths algorithm to compute the +sum of squared distances to all vertices from the lexicographically +smallest vertex \f$v_0\f$ in the arrangement. Note the usage of the +`Arr_vertex_property_map` class template in the call to +`boost::dijkstra_shortest_paths()` and in the definition of the +distance property-map. We instantiate a property map that attaches a +number of type `Number_type` (which is a type of unlimited precision) +to each vertex. The number represents the sum of squared distances of +the vertex from $v_0$. \cgalExample{Arrangement_on_surface_2/bgl_primal_adapter.cpp} @@ -6792,15 +6802,16 @@ dual interpretation to an arrangement instance. In a dual representation, \link Arrangement_on_surface_2::Face_handle `Face_handle`\endlink is the graph-vertex type, while \link -Arrangement_on_surface_2::Halfedge_handle `Halfedge_handle`\endlink is the -graph-edge type. We treat the graph edges as directed, such that a +Arrangement_on_surface_2::Halfedge_handle `Halfedge_handle`\endlink is +the graph-edge type. We treat the graph edges as directed, such that a halfedge `e` is directed from \f$f_1\f$, which is its incident face, to \f$f_2\f$, which is the incident face of its twin halfedge. As two arrangement faces may share more than a single edge on their boundary, -we allow parallel edges (loops) in our \sc{Boost} graph. As is the -case in the primal graph, the dual arrangement graph is also a model -of the concepts `VertexListGraph`, `EdgeListGraph` and -`BidirectionalGraph` (thus also of `IncidenceGraph`). +we allow parallel edges (loops) in our Boost graph. As is the case in the primal graph, +the dual arrangement graph is also a model of the concepts +`VertexListGraph`, `EdgeListGraph` and `BidirectionalGraph` (thus also +of `IncidenceGraph`). Since we use \link Arrangement_on_surface_2::Face_handle `Face_handle`\endlink objects as the vertex descriptors, we define the @@ -6859,7 +6870,7 @@ the program coded in \ref Arrangement_on_surface_2/bgl_primal_adapter.cpp; see \cgalFigureRef{aos_fig-bgl_primal_adapter}. Then, it performs a breadth-first search traversal on the face graph, starting from the -unbounded face. The \sc{Dcel} faces are extended with an unsigned +unbounded face. The \dcel faces are extended with an unsigned integer indicating the discovered time of the face. The code uses a visitor that obtains the times and writes them into a property map that updates the faces @@ -6889,7 +6900,7 @@ insertion-functions instead of the general ones; e.g., `insert()`.
  • When the curves to be inserted into an arrangement are segments that are pairwise disjoint in their interior, it is more efficient to use -the traits class `Arr_non_caching_segment_traits_2` rather then +the traits class `Arr_non_caching_segment_traits_2` rather than the default one (`Arr_segment_traits_2`). If the segments may intersect each other, the default traits class @@ -6900,7 +6911,8 @@ On rare occasions the traits class `Arr_non_caching_segment_traits_2` exhibits slightly better performance than the default one (`Arr_segment_traits_2` even when the segments intersect each other, due to the small overhead of the latter (optimized) traits class. (For -example, when the so-called \sc{Leda} rational kernel is used.) +example, when the so-called Leda rational +kernel is used.)
  • Prior knowledge of the combinatorial structure of the arrangement can be used to accelerate operations that insert \f$x\f$-monotone @@ -6912,7 +6924,7 @@ the arrangement. The specialized insertion functions, i.e., `Arrangement_on_surface_2::insert_at_vertices()` can be used according to the available information. These functions hardly involve any geometric operations, if at all. They accept topologically related -parameters, and use them to operate directly on the \sc{Dcel} records, +parameters, and use them to operate directly on the \dcel records, thus saving algebraic operations, which are especially expensive when high-degree curves are involved. diff --git a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_polycurve_traits_2.h b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_polycurve_traits_2.h index 16788a94596..99d4f50fbf4 100644 --- a/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_polycurve_traits_2.h +++ b/Arrangement_on_surface_2/doc/Arrangement_on_surface_2/CGAL/Arr_polycurve_traits_2.h @@ -408,7 +408,7 @@ namespace CGAL { size_type number_of_subcurves() const; /*! Obtain the \f$ k\f$th subcurve of the polycurve. - * \pre \f$k\f$ is not greater then or equal to \f$n-1\f$, where + * \pre \f$k\f$ is not greater than or equal to \f$n-1\f$, where * \f$n\f$ is the number of subcurves. */ typename SubcurveTraits_2::X_monotone_curve_2 diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h b/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h index 124d655c17f..ab685eaed54 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_dcel_base.h @@ -479,7 +479,18 @@ public: const Inner_ccb* inner_ccb() const { CGAL_precondition(is_on_inner_ccb()); - return (reinterpret_cast(_clean_pointer(this->p_comp))); + + const Inner_ccb* out = reinterpret_cast(_clean_pointer(this->p_comp)); + if (out->is_valid()) + return out; + + // else reduce path and get valid iccb + const Inner_ccb* valid = out->next(); + while (!valid->is_valid()) + valid = valid->next(); + const_cast(out)->set_next(const_cast(valid)); + const_cast(this)->set_inner_ccb(valid); + return valid; } /*! Obtain an incident inner CCB (non-const version). @@ -488,11 +499,28 @@ public: Inner_ccb* inner_ccb() { CGAL_precondition(is_on_inner_ccb()); - return (reinterpret_cast(_clean_pointer(this->p_comp))); + + Inner_ccb* out = reinterpret_cast(_clean_pointer(this->p_comp)); + if (out->is_valid()) + return out; + + // else reduce path and get valid iccb + Inner_ccb* valid = out->next(); + while (!valid->is_valid()) + valid = valid->next(); + out->set_next(valid); + set_inner_ccb(valid); + return valid; + } + + Inner_ccb* inner_ccb_no_redirect() + { + CGAL_precondition(is_on_inner_ccb()); + return reinterpret_cast(_clean_pointer(this->p_comp)); } /*! Set the incident inner CCB. */ - void set_inner_ccb(Inner_ccb *ic) + void set_inner_ccb(const Inner_ccb *ic) { // Set the component pointer and set its LSB. this->p_comp = _set_lsb(ic); @@ -769,18 +797,29 @@ public: typedef typename Face::Inner_ccb_iterator Inner_ccb_iterator; private: - Face* p_f; // The face the contains the CCB in its interior. + union + { + Face* f; // The face the contains the CCB in its interior. + Arr_inner_ccb* icc; // next inner CCB in chain to valid icc + } f_or_icc; Inner_ccb_iterator iter; // The inner CCB identifier. - bool iter_is_not_singular; + enum + { + ITER_IS_SINGULAR, // singular = default iterator, not initialized + ITER_IS_NOT_SINGULAR, // not singular = iterator was assigned and is valid + INVALID // invalid = the inner CCB is invalid and + // only links to another inner CCB + // in chain to valid CCB + } status; public: /*! Default constructor. */ - Arr_inner_ccb() : p_f(nullptr), iter_is_not_singular(false) {} + Arr_inner_ccb() : status(ITER_IS_SINGULAR) { f_or_icc.f = nullptr; } /*! Copy constructor. */ Arr_inner_ccb(const Arr_inner_ccb& other) : - p_f(other.p_f), iter_is_not_singular(other.iter_is_not_singular) - { if (other.iter_is_not_singular) iter = other.iter; } + f_or_icc(other.f_or_icc), status(other.status) + { if (other.status == ITER_IS_NOT_SINGULAR) iter = other.iter; } /*! Obtain a halfedge along the component (const version). */ const Halfedge* halfedge() const { return (*iter); } @@ -789,7 +828,11 @@ public: Halfedge* halfedge() { return (*iter); } /*! Set a representative halfedge for the component. */ - void set_halfedge(Halfedge *he) { *iter = he; } + void set_halfedge(Halfedge *he) + { + CGAL_assertion (is_valid()); + *iter = he; + } /*! Obtain the incident face (const version). */ const Face* face() const { return (p_f); } @@ -798,28 +841,51 @@ public: Face* face() { return (p_f); } /*! Set the incident face. */ - void set_face(Face* f) { p_f = f; } + void set_face(Face* f) + { + CGAL_assertion (status != INVALID); + f_or_icc.f = f; + } /*! Obtain the iterator (const version). */ Inner_ccb_iterator iterator() const { - CGAL_assertion(iter_is_not_singular); + CGAL_assertion(status == ITER_IS_NOT_SINGULAR); return (iter); } /*! Obtain the iterator (non-const version). */ Inner_ccb_iterator iterator() { - CGAL_assertion(iter_is_not_singular); + CGAL_assertion(status == ITER_IS_NOT_SINGULAR); return (iter); } /*! Set the inner CCB iterator. */ void set_iterator(Inner_ccb_iterator it) { + CGAL_assertion (is_valid()); iter = it; - iter_is_not_singular = true; + status = ITER_IS_NOT_SINGULAR; } + + /*! Check validity */ + bool is_valid() const { return (status != INVALID); } + + /*! Get the next CCB to primary chain. */ + Arr_inner_ccb* next() const + { + CGAL_assertion (status == INVALID); + return f_or_icc.icc; + } + + /*! Set the next CCB to primary chain. */ + void set_next(Arr_inner_ccb* next) + { + status = INVALID; + f_or_icc.icc = next; + } + }; /*! \class @@ -943,6 +1009,7 @@ public: typedef typename Face_list::iterator Face_iterator; typedef CGAL::N_step_adaptor_derived Edge_iterator; + typedef typename Inner_ccb_list::iterator Inner_ccb_iterator; // Definitions of const iterators. typedef typename Vertex_list::const_iterator Vertex_const_iterator; @@ -1019,6 +1086,9 @@ public: { return make_prevent_deref_range(edges_begin(), edges_end()); } + + Inner_ccb_iterator inner_ccbs_begin() { return in_ccbs.begin(); } + Inner_ccb_iterator inner_ccbs_end() { return in_ccbs.end(); } //@} /// \name Obtaining constant iterators. diff --git a/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h b/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h index 393958f3424..285faa4c183 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arr_overlay_2.h @@ -168,7 +168,7 @@ overlay(const Arrangement_on_surface_2& arr1 typedef Arrangement_on_surface_2 Arr_res; typedef typename Arr_res::Allocator Allocator; - // some type assertions (not all, but better then nothing). + // some type assertions (not all, but better than nothing). #if !defined(CGAL_NO_ASSERTIONS) typedef typename Agt2::Point_2 A_point; typedef typename Bgt2::Point_2 B_point; diff --git a/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_impl.h b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_impl.h index 36c9a9a19ce..c7bb1aa1bdf 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_impl.h +++ b/Arrangement_on_surface_2/include/CGAL/Arrangement_2/Arrangement_on_surface_2_impl.h @@ -2781,14 +2781,24 @@ _insert_at_vertices(DHalfedge* he_to, he1->set_inner_ccb(ic1); he2->set_inner_ccb(ic1); - // Make all halfedges along ic2 to point to ic1. - DHalfedge* curr; + if (m_sweep_mode) + { + // Inner CCB are obtained using Halfedge::inner_ccb() which + // performs path reduction and always return valid iCCB + CGAL_assertion(ic1->is_valid()); + CGAL_assertion(ic2->is_valid()); + ic2->set_next(ic1); + } + else + { + // Make all halfedges along ic2 to point to ic1. + DHalfedge* curr; + for (curr = he2->next(); curr != he1; curr = curr->next()) + curr->set_inner_ccb(ic1); - for (curr = he2->next(); curr != he1; curr = curr->next()) - curr->set_inner_ccb(ic1); - - // Delete the redundant inner CCB. - _dcel().delete_inner_ccb(ic2); + // Delete the redundant inner CCB. + _dcel().delete_inner_ccb(ic2); + } // Notify the observers that we have merged the two inner CCBs. _notify_after_merge_inner_ccb(fh, (Halfedge_handle(he1))->ccb()); @@ -4097,7 +4107,7 @@ _defines_outer_ccb_of_new_face(const DHalfedge* he_to, // - No smallest has bin recorded so far, or // - The current target vertex and the recorded vertex are the same and // * The current curve is smaller than the recorded curve, or - // - The current curve end is smaller then the recorded curve end. + // - The current curve end is smaller than the recorded curve end. // smaller than its source, so we should check whether it is also smaller // Note that we compare the vertices lexicographically: first by the // indices, then by x, then by y. diff --git a/Arrangement_on_surface_2/include/CGAL/Arrangement_on_surface_2.h b/Arrangement_on_surface_2/include/CGAL/Arrangement_on_surface_2.h index 5ffc0a5abd1..505dc543431 100644 --- a/Arrangement_on_surface_2/include/CGAL/Arrangement_on_surface_2.h +++ b/Arrangement_on_surface_2/include/CGAL/Arrangement_on_surface_2.h @@ -913,6 +913,14 @@ protected: bool m_own_traits; // inidicates whether the geometry // traits should be freed up. + bool m_sweep_mode = false; + // sweep mode efficiently + // merges inner CCB but + // keeps invalid inner CCB + // and memory overhead that + // should be cleaned + // afterwards + public: /// \name Constructors. //@{ @@ -943,6 +951,9 @@ public: /*! Destructor. */ virtual ~Arrangement_on_surface_2(); + /*! Change mode. */ + void set_sweep_mode (bool mode) { m_sweep_mode = mode; } + /*! Clear the arrangement. */ virtual void clear(); //@} @@ -1520,6 +1531,39 @@ public: //@} + /*! + * Cleans the inner CCB if sweep mode was used, by removing all + * non-valid inner CCBs + */ + void clean_inner_ccbs_after_sweep() + { + for (DHalfedge_iter he = _dcel().halfedges_begin(); + he != _dcel().halfedges_end(); ++ he) + { + if (!he->is_on_inner_ccb()) + continue; + + DInner_ccb* ic1 = he->inner_ccb_no_redirect(); + if (ic1->is_valid()) + continue; + + // Calling Halfedge::inner_ccb() reduces the path and makes the + // halfedge point to a correct CCB + DInner_ccb* ic2 = he->inner_ccb(); + CGAL_USE(ic2); + CGAL_assertion (ic2->halfedge()->is_on_inner_ccb() + && ic2->halfedge()->inner_ccb_no_redirect() == ic2); + } + + typename Dcel::Inner_ccb_iterator it = _dcel().inner_ccbs_begin(); + while (it != _dcel().inner_ccbs_end()) + { + typename Dcel::Inner_ccb_iterator current = it ++; + if (!current->is_valid()) + _dcel().delete_inner_ccb(&*current); + } + } + protected: /// \name Determining the boundary-side conditions. //@{ diff --git a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_construction_ss_visitor.h b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_construction_ss_visitor.h index 04bfaf4ea62..bfed0a3020f 100644 --- a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_construction_ss_visitor.h +++ b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_construction_ss_visitor.h @@ -154,6 +154,9 @@ public: /* A notification issued before the sweep process starts. */ inline void before_sweep(); + /* A notification issued after the sweep process stops. */ + inline void after_sweep(); + /*! * A notification invoked before the sweep-line starts handling the given * event. @@ -288,7 +291,21 @@ private: // Notifies the helper that the sweep process now starts. template void Arr_construction_ss_visitor::before_sweep() -{ m_helper.before_sweep(); } +{ + m_helper.before_sweep(); + m_arr->set_sweep_mode(true); +} + + +//----------------------------------------------------------------------------- +// A notification issued after the sweep process stops. +template +void Arr_construction_ss_visitor::after_sweep() +{ + m_arr->clean_inner_ccbs_after_sweep(); + m_arr->set_sweep_mode(false); +} + //----------------------------------------------------------------------------- // A notification invoked before the sweep-line starts handling the given diff --git a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h index 81227d4f2b2..510fa90958d 100644 --- a/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h +++ b/Arrangement_on_surface_2/include/CGAL/Surface_sweep_2/Arr_overlay_ss_visitor.h @@ -552,6 +552,8 @@ Arr_overlay_ss_visitor::update_event(Event* e, template void Arr_overlay_ss_visitor::after_sweep() { + Base::after_sweep(); + // Notify boundary vertices: typename Vertex_map::iterator it; for (it = m_vertices_map.begin(); it != m_vertices_map.end(); ++it) { 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 bc3f1b89e7a..8490bea5ce7 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 @@ -9,20 +9,6 @@ enable_testing() find_package(CGAL REQUIRED COMPONENTS Core) include(${CGAL_USE_FILE}) - -if(COMMAND target_compile_options) - # Since CMake-2.8.12: New CMake script, that defines the targets and - # the CTest test cases. - include(${CMAKE_CURRENT_SOURCE_DIR}/cgal_test.cmake) -else() - # If CMake version is <= 2.8.11, use the usual CMake script. - - # create a target per cppfile - file( - GLOB cppfiles - RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) - foreach(cppfile ${cppfiles}) - create_single_source_cgal_program("${cppfile}") - endforeach() -endif() +# Since CMake-2.8.12: New CMake script, that defines the targets and +# the CTest test cases. +include(${CMAKE_CURRENT_SOURCE_DIR}/cgal_test.cmake) diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test.cmake b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test.cmake index bfca1eaa73a..07947bb68bc 100644 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test.cmake +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test.cmake @@ -1400,3 +1400,9 @@ compile_and_run(test_io) compile_and_run(test_sgm) compile_and_run(test_polycurve_intersection) +if(CGAL_DISABLE_GMP) + get_directory_property(LIST_OF_TESTS TESTS) + foreach(_test ${LIST_OF_TESTS}) + set_property(TEST ${_test} APPEND PROPERTY ENVIRONMENT CGAL_DISABLE_GMP=1) + endforeach() +endif() diff --git a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test_with_cmake b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test_with_cmake index c1183a846d8..2b9a9aee225 100755 --- a/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test_with_cmake +++ b/Arrangement_on_surface_2/test/Arrangement_on_surface_2/cgal_test_with_cmake @@ -129,22 +129,36 @@ configure() { echo "Configuring... " rm -rf CMakeCache.txt CMakeFiles/ - echo "cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ - -DCGAL_DIR=\"$CGAL_DIR\" \ - -DCGAL_CXX_FLAGS:STRING=\"$TESTSUITE_CXXFLAGS -I../../include\" \ - -DCGAL_EXE_LINKER_FLAGS=\"$TESTSUITE_LDFLAGS\" \ - -DCMAKE_BUILD_TYPE=NOTFOUND \ - ." - if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ - -DCGAL_DIR="$CGAL_DIR" \ - -DCGAL_CXX_FLAGS:STRING="$TESTSUITE_CXXFLAGS -I../../include" \ - -DCGAL_EXE_LINKER_FLAGS="$TESTSUITE_LDFLAGS" \ - -DCMAKE_BUILD_TYPE=NOTFOUND \ - .' ; then + if [ -f "$INIT_FILE" ] + then + if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ + -DCGAL_DIR="$CGAL_DIR" \ + -DCGAL_CXX_FLAGS:STRING="$CGAL_CXX_FLAGS $TESTSUITE_CXXFLAGS -I../../include" \ + -DCGAL_EXE_LINKER_FLAGS="$CGAL_EXE_LINKER_FLAGS $TESTSUITE_LDFLAGS" \ + .' ; then - echo " successful configuration" >> $ERRORFILE + echo " successful configuration" >> $ERRORFILE + else + echo " ERROR: configuration" >> $ERRORFILE + fi else - echo " ERROR: configuration" >> $ERRORFILE + echo "cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ + -DCGAL_DIR=\"$CGAL_DIR\" \ + -DCGAL_CXX_FLAGS:STRING=\"$TESTSUITE_CXXFLAGS -I../../include\" \ + -DCGAL_EXE_LINKER_FLAGS=\"$TESTSUITE_LDFLAGS\" \ + -DCMAKE_BUILD_TYPE=NOTFOUND \ + ." + if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ + -DCGAL_DIR="$CGAL_DIR" \ + -DCGAL_CXX_FLAGS:STRING="$TESTSUITE_CXXFLAGS -I../../include" \ + -DCGAL_EXE_LINKER_FLAGS="$TESTSUITE_LDFLAGS" \ + -DCMAKE_BUILD_TYPE=NOTFOUND \ + .' ; then + + echo " successful configuration" >> $ERRORFILE + else + echo " ERROR: configuration" >> $ERRORFILE + fi fi } diff --git a/BGL/doc/BGL/BGL.txt b/BGL/doc/BGL/BGL.txt index 8f84610bdaf..24d47005b6d 100644 --- a/BGL/doc/BGL/BGL.txt +++ b/BGL/doc/BGL/BGL.txt @@ -16,9 +16,9 @@ faces as edges of the dual graph. The scope of \cgal is geometry and not graph algorithms. Nevertheless, this package provides the necessary classes and functions that enable using the algorithms of the Boost Graph Library \cgalCite{cgal:sll-bgl-02} -(\sc{Bgl} for short) with \cgal data structures. +(\bgl for short) with \cgal data structures. -Furthermore, this package extends the \sc{Bgl} +Furthermore, this package extends the \bgl by introducing concepts such as `HalfedgeGraph` and `FaceGraph` allowing to handle *halfedges* and *faces*. These concepts reflect the design of the halfedge data structure described @@ -26,7 +26,7 @@ in Chapter \ref PkgHalfedgeDS, with opposite halfedges and circular sequences of halfedges around vertices and around faces. This chapter is organized as follows: -- The first section, Section \ref BGLA, summarizes the main ideas of the \sc{Bgl}. +- The first section, Section \ref BGLA, summarizes the main ideas of the \bgl. - Section \ref BGLHeader then explains where to find header files and the chosen naming conventions, as we blend two different libraries. - The four following sections give examples on how to use CGAL graph and mesh data structures @@ -34,13 +34,13 @@ such as \link PkgSurfaceMesh Surface_mesh \endlink, \link PkgPolyhedron Polyhedron \endlink, \link PkgArrangementOnSurface2 Arrangement_2 \endlink, and the -\link PkgTriangulation2 2D triangulation \endlink classes as models of the \sc{Bgl} concepts. +\link PkgTriangulation2 2D triangulation \endlink classes as models of the \bgl concepts. - Starting with Section \ref BGLExtensions, we introduce new graph concepts, classes, -and functions that extend the functionalities of the \sc{Bgl}. +and functions that extend the functionalities of the \bgl. \section BGLA A Short Introduction to the Boost Graph Library -The algorithms of the \sc{Bgl} operate on models of various graph concepts. +The algorithms of the \bgl operate on models of various graph concepts. The traits class `boost::graph_traits` enable algorithms to determine the types of vertices and edges (similar to `std::iterator_traits` for iterators). Free functions that operate on graphs enable algorithms to obtain, @@ -53,7 +53,7 @@ arbitrary order. \subsection BGLGraphConcepts Graph Concepts -The \sc{Bgl} introduces several graph concepts, +The \bgl introduces several graph concepts, which have different sets of characteristics and requirements. For example, iterating through all vertices or all edges in a graph, obtaining the outgoing or in-going edges of a vertex, inserting vertices and edges into a graph, @@ -101,16 +101,16 @@ std::pair vertices(const Graph& g); \subsection BGLPropertyMaps Property Maps -Another feature extensively used in the \sc{Bgl} is the *property map*, +Another feature extensively used in the \bgl is the *property map*, which is offered by the Boost Property Map Library. Property maps are a general purpose interface for mapping key objects to corresponding value objects. -The \sc{Bgl} uses property maps to associate information with vertices and edges. +The \bgl uses property maps to associate information with vertices and edges. This mechanism uses a traits class (`boost::property_traits`) and free functions to read (`get`) and write (`put`) information in vertices, edges, and also in halfedges and faces for models of the \cgal graph concepts. -For example, the \sc{Bgl} +For example, the \bgl Dijksta's shortest path algorithm writes the predecessor of each vertex, as well as the distance to the source in such a property map. @@ -138,14 +138,14 @@ Examples of such event points in graph algorithms are when a vertex is traversed or when all outgoing edges of a vertex have been traversed.
    See also Section Visitor Concepts -in the \sc{Bgl} manual. +in the \bgl manual. \subsection BGLNamedParameters Named Parameters -The notion of named parameters was introduced in the \sc{Bgl}, +The notion of named parameters was introduced in the \bgl, and allow the user to specify only those parameters which are really needed, by name, making the parameter ordering unimportant. See also this page -in the manual of the \sc{Bgl} for more information. +in the manual of the \bgl for more information. Say there is a function `f()` that takes 3 parameters called name, age and gender, and you have variables `n`, `a` and `g` to pass as parameters to that function. @@ -186,32 +186,32 @@ refine(pmesh, \section BGLHeader Header Files, Namespaces, and Naming Conventions This package provides the necessary classes and functions that enable using -\cgal data structures as models of the \sc{Bgl} graph concepts. +\cgal data structures as models of the \bgl graph concepts. To this end, we offer partial specializations of the `boost::graph_traits` for various \cgal packages. For each such package, denoted `PACKAGE`, the partial specializations live in the namespace `boost` and are located in the header file `CGAL/boost/graph/graph_traits_PACKAGE.h`. Free functions are in the namespace `CGAL`, and the compiler uses argument-dependent lookup to find them. %Euler operations, described in Section \ref BGLEulerOperations, are in the namespace `CGAL::Euler`, as the function `remove_face()` is at the same time a low-level and an %Euler operation. -Concerning the naming conventions, we have to use those of the \sc{Bgl}, -as to fulfill the requirements of the concepts defined in the \sc{Bgl}. +Concerning the naming conventions, we have to use those of the \bgl, +as to fulfill the requirements of the concepts defined in the \bgl. Note that these partial specializations are often providing more than is required, making these classes not only models of the graph concepts -of the \sc{Bgl}, but also models of the CGAL graph concepts, that will be +of the \bgl, but also models of the CGAL graph concepts, that will be described in detail in Section \ref BGLExtensions. Correspondence tables -between the types of a \cgal data structure and their \sc{Bgl} equivalents +between the types of a \cgal data structure and their \bgl equivalents can be found in the \ref PkgBGLTraits documentation page. We present in the following sections some examples of utilization of some -\cgal data structures as \sc{Bgl} graphs. +\cgal data structures as \bgl graphs. \section BGLSurface_mesh The Class Surface_mesh as Model of the Boost Graph Concept -The class `Surface_mesh` is a model of most of the graph concepts of the \sc{Bgl} +The class `Surface_mesh` is a model of most of the graph concepts of the \bgl as well as the concepts provided by \cgal. A complete list can be found in the documentation of \link BGLSMGT boost::graph_traits \endlink. -The examples show how to use some of the \sc{Bgl} algorithms with `Surface_mesh` and show how to use +The examples show how to use some of the \bgl algorithms with `Surface_mesh` and show how to use the concepts provided by \cgal to implement a simple algorithm. \subsection BGLExampleMinimumSpanningTreeofaSurfaceMesh Example: Minimum Spanning Tree of a Surface_mesh @@ -221,16 +221,16 @@ More examples can be found in Chapters \ref PkgSurfaceMeshSimplification, \ref PkgSurfaceMeshSegmentation, and \ref PkgSurfaceMeshDeformation. The surface mesh class uses integer indices to address vertices and edges, -and it comes with a built-in property mechanism that maps nicely on the \sc{Bgl}. +and it comes with a built-in property mechanism that maps nicely on the \bgl. \cgalExample{BGL_surface_mesh/prim.cpp} \section BGLPolyhedral The Class Polyhedron_3 as Model of the Boost Graph Concept -The class `Polyhedron_3` is a model of most of the graph concepts of the \sc{Bgl} +The class `Polyhedron_3` is a model of most of the graph concepts of the \bgl as well as the concepts provided by \cgal. A complete list can be found in the documentation of \link BGLPolyGT boost::graph_traits \endlink. -The examples show how to use some of the \sc{Bgl} algorithms with `Polyhedron_3` and show how to use +The examples show how to use some of the \bgl algorithms with `Polyhedron_3` and show how to use the concepts provided by \cgal to implement a simple algorithm. \subsection BGLExampleMinimumSpanningTreeofaPolyhedral Example: Minimum Spanning Tree of a Polyhedral Surface @@ -243,7 +243,7 @@ More examples can be found in the Chapter \subsection BGLExampleUsingVerticesandEdgeswithanID Example: Using Vertices, and Edges with an ID -The following example program shows a call to the \sc{Bgl} +The following example program shows a call to the \bgl Kruskal's minimum spanning tree algorithm accessing the `id()` field stored in a polyhedron vertex. @@ -275,7 +275,7 @@ integers in the range `[0, t.number_of_vertices())`. \subsection BGLExampleStoringtheVertexIDintheVertex Example: Storing the Vertex ID in the Vertex -The algorithms of the \sc{Bgl} extensively use of the indices of +The algorithms of the \bgl extensively use of the indices of vertices. In the previous example we stored the indices in a `std::map` and turned that map in a property map. This property map was then passed as argument to the shortest path function. @@ -316,7 +316,7 @@ edges in our boost graph. Given an `Arrangement_2` instance, we can efficiently traverse its vertices and halfedges. Thus, the arrangement graph is a model of the concepts -`VertexListGraph` and `EdgeListGraph` introduced by the \sc{Bgl}. +`VertexListGraph` and `EdgeListGraph` introduced by the \bgl. At the same time, we use an iterator adapter of the circulator over the halfedges incident to a vertex (`Halfedge_around_target_circulator` - see Section \ref arr_sssectr_vertex "Traversal Methods for an Arrangement Vertex" @@ -327,11 +327,11 @@ is a model of the concept `BidirectionalGraph` (this concept refines It is important to notice that the vertex descriptors we use are `Vertex_handle` objects and not vertex indices. However, in order -to gain more efficiency in most \sc{Bgl} algorithm, it is better to have them +to gain more efficiency in most \bgl algorithm, it is better to have them indexed \f$ 0, 1, \ldots, (n-1)\f$, where \f$ n\f$ is the number of vertices. We therefore introduce the `Arr_vertex_index_map` class-template, which maintains a mapping of vertex handles to indices, as required by the -\sc{Bgl}. An instance of this class must be attached to a valid arrangement +\bgl. An instance of this class must be attached to a valid arrangement vertex when it is created. It uses the notification mechanism (see Section \ref arr_ssecnotif) to automatically maintain the mapping of vertices to indices, even when new vertices are inserted into the arrangement or @@ -340,7 +340,7 @@ existing vertices are removed. A complete description of the types correspondences can be found in the documentation of \link BGLArgtGT boost::graph_traits \endlink. -In most algorithm provided by the \sc{Bgl}, the output is given by +In most algorithm provided by the \bgl, the output is given by property maps, such that each map entry corresponds to a vertex. For example, when we compute the shortest paths from a given source vertex \f$ s\f$ to all other vertices we can obtain a map of distances and a map of @@ -353,7 +353,7 @@ template allows for an efficient mapping of `Vertex_handle` objects to properties of type `Type`. Note however that unlike the `Arr_vertex_index_map` class, the vertex property-map class is not kept synchronized with the number of vertices in the arrangement, so it -should not be reused in calls to the \sc{Bgl} functions in case the arrangement +should not be reused in calls to the \bgl functions in case the arrangement is modified in between these calls. \cgalFigureBegin{figex_bgl,ex_bgl.png} @@ -364,7 +364,7 @@ faces, starting from the unbounded face \f$ f_0\f$, are shown in brackets. In the following example we construct an arrangement of 7 line segments, as shown in \cgalFigureRef{figex_bgl}, -then use the \sc{Bgl} Dijkstra's shortest-paths algorithm to compute +then use the \bgl Dijkstra's shortest-paths algorithm to compute the graph distance of all vertices from the leftmost vertex in the arrangement \f$ v_0\f$. Note the usage of the `Arr_vertex_index_map` and the `Arr_vertex_property_map` classes. The latter one, instantiated by @@ -413,9 +413,9 @@ these times and update the faces accordingly: The previous sections introduced partial specializations and free functions so that several \cgal data structures are adapted as models of some -of the \sc{Bgl} graph concepts. +of the \bgl graph concepts. In this section, we introduce new concepts, iterators, and property maps inspired -by the functionalities of the \sc{Bgl}. +by the functionalities of the \bgl. \subsection BGLExtensionsGraphConcepts Graph concepts @@ -487,7 +487,7 @@ stored in the vertex record.) \subsubsection BGLExampleNormalHalfedgeGraph Example: Calculating Facet Normals using HalfedgeGraph The following example program shows a simple algorithm for calculating -facet normals for a polyhedron using the \sc{Bgl} API. A +facet normals for a polyhedron using the \bgl API. A boost::vector_property_map is used to to store the calculated normals instead of changing the Polyhedron items class. @@ -581,13 +581,13 @@ as shown in the following example. \subsection BGLSeamMesh The Seam Mesh The class `Seam_mesh` allows to mark edges of a mesh as seam edges -so that they virtually become border edges when exploring a seam mesh with the \sc{Bgl} API. +so that they virtually become border edges when exploring a seam mesh with the \bgl API. The input mesh is referred to as underlying mesh of the seam mesh. We denote `tm` and `sm` the underlying mesh and the seam mesh respectively. Figure \cgalFigureRef{fig_Seam_mesh_1} shows an example of mesh on which two edges, defined by the halfedge pairs `h2-h3` and `h6-h7`, are marked as seams. -The introduction of virtual borders modifies the elementary \sc{Bgl} graph traversal +The introduction of virtual borders modifies the elementary \bgl graph traversal operations: when we circulate around the target of `h7` in the underlying mesh, we traverse `h7`, `h1`, `h3`, `h5`, before arriving at `h7` again. However, when we circulate in the seam mesh, we traverse `h7`, `h1`, `h3*`, diff --git a/BGL/doc/BGL/CGAL/HalfedgeDS_face_max_base_with_id.h b/BGL/doc/BGL/CGAL/HalfedgeDS_face_max_base_with_id.h index c106f1d9644..5518ffb5c0c 100644 --- a/BGL/doc/BGL/CGAL/HalfedgeDS_face_max_base_with_id.h +++ b/BGL/doc/BGL/CGAL/HalfedgeDS_face_max_base_with_id.h @@ -9,7 +9,7 @@ concept. It is equivalent to `HalfedgeDS_face_base< Refs, Tag_true>` with an added integer field which can be used to index faces -in \sc{Bgl} algorithms. +in \bgl algorithms. The class contains support for the incident halfedge pointer and the required type definitions. It can be used for deriving own faces. diff --git a/BGL/doc/BGL/CGAL/HalfedgeDS_halfedge_max_base_with_id.h b/BGL/doc/BGL/CGAL/HalfedgeDS_halfedge_max_base_with_id.h index 965f513863a..f57951dc82e 100644 --- a/BGL/doc/BGL/CGAL/HalfedgeDS_halfedge_max_base_with_id.h +++ b/BGL/doc/BGL/CGAL/HalfedgeDS_halfedge_max_base_with_id.h @@ -7,7 +7,7 @@ namespace CGAL { The class `HalfedgeDS_halfedge_max_base_with_id` is a model of the `HalfedgeDSHalfedge` concept. It is equivalent to `HalfedgeDS_halfedge_base< Refs, Tag_true, Tag_true, Tag_true>` with an added integer -field which can be used to index halfedges in \sc{Bgl} algorithms. +field which can be used to index halfedges in \bgl algorithms. The class contains support for the previous, next, opposite, vertex and face pointers and the required type definitions. It can be used for deriving own halfedges. diff --git a/BGL/doc/BGL/CGAL/HalfedgeDS_vertex_max_base_with_id.h b/BGL/doc/BGL/CGAL/HalfedgeDS_vertex_max_base_with_id.h index 328c65aa8c4..15fad92af97 100644 --- a/BGL/doc/BGL/CGAL/HalfedgeDS_vertex_max_base_with_id.h +++ b/BGL/doc/BGL/CGAL/HalfedgeDS_vertex_max_base_with_id.h @@ -8,7 +8,7 @@ The class `HalfedgeDS_vertex_max_base_with_id` is a model of the `HalfedgeDSVert concept. It is equivalent to `HalfedgeDS_vertex_base< Refs, Tag_true>` with an added integer field which can be used to index vertices -in \sc{Bgl} algorithms.. +in \bgl algorithms.. The class contains support for the point and the required type definitions. It can be used for deriving own vertices. diff --git a/BGL/doc/BGL/CGAL/Polyhedron_items_with_id_3.h b/BGL/doc/BGL/CGAL/Polyhedron_items_with_id_3.h index 91f9fa32188..7db19153e87 100644 --- a/BGL/doc/BGL/CGAL/Polyhedron_items_with_id_3.h +++ b/BGL/doc/BGL/CGAL/Polyhedron_items_with_id_3.h @@ -7,7 +7,7 @@ namespace CGAL { The class `Polyhedron_items_with_id_3` is a model of the `PolyhedronItems_3` concept. It provides definitions for vertices with points, halfedges, and faces with plane equations, all of them with an additional integer -field which can be used to index the items in a \sc{Bgl} algorithm. +field which can be used to index the items in a \bgl algorithm. The polyhedron traits class must provide the respective types for the point and the plane equation. Vertices and facets both contain a halfedge handle to an incident diff --git a/BGL/doc/BGL/CGAL/Triangulation_face_base_with_id_2.h b/BGL/doc/BGL/CGAL/Triangulation_face_base_with_id_2.h index e1b380ac939..e6bdbbc6577 100644 --- a/BGL/doc/BGL/CGAL/Triangulation_face_base_with_id_2.h +++ b/BGL/doc/BGL/CGAL/Triangulation_face_base_with_id_2.h @@ -6,7 +6,7 @@ namespace CGAL { The class `Triangulation_face_base_with_id_2` is a model of the concept `TriangulationFaceBase_2`, the base face of a 2D-triangulation. It provides an integer field that can be used to -index faces for \sc{Bgl} algorithms. +index faces for \bgl algorithms. Note that the user is in charge of setting indices correctly before running a graph algorithm, by calling the function diff --git a/BGL/doc/BGL/CGAL/Triangulation_vertex_base_with_id_2.h b/BGL/doc/BGL/CGAL/Triangulation_vertex_base_with_id_2.h index 0c71e6b72af..d9a58761062 100644 --- a/BGL/doc/BGL/CGAL/Triangulation_vertex_base_with_id_2.h +++ b/BGL/doc/BGL/CGAL/Triangulation_vertex_base_with_id_2.h @@ -6,7 +6,7 @@ namespace CGAL { The class `Triangulation_vertex_base_with_id_2` is a model of the concept `TriangulationVertexBase_2`, the base vertex of a 2D-triangulation. It provides an integer field that can be used to -index vertices for \sc{Bgl} algorithms. +index vertices for \bgl algorithms. Note that the user is in charge of setting indices correctly before running a graph algorithm, by calling the function diff --git a/BGL/doc/BGL/CGAL/boost/graph/properties.h b/BGL/doc/BGL/CGAL/boost/graph/properties.h index 40ca966a8e2..01f6df7b62f 100644 --- a/BGL/doc/BGL/CGAL/boost/graph/properties.h +++ b/BGL/doc/BGL/CGAL/boost/graph/properties.h @@ -4,7 +4,7 @@ namespace CGAL { /// \ingroup PkgBGLProperties /// @{ -/// The constant `vertex_index` is a property tag which identifies the index property of a vertex of a \sc{Bgl} +/// The constant `vertex_index` is a property tag which identifies the index property of a vertex of a \bgl /// Graph. /// \cgalModels PropertyTag enum vertex_index_t { vertex_index }; @@ -15,7 +15,7 @@ enum vertex_index_t { vertex_index }; /// \cgalModels PropertyTag enum halfedge_index_t { halfedge_index }; -/// The constant `edge_index` is a property tag which identifies the index property of an edge of a \sc{Bgl} +/// The constant `edge_index` is a property tag which identifies the index property of an edge of a \bgl /// Graph. /// \cgalModels PropertyTag enum edge_index_t { edge_index }; diff --git a/BGL/doc/BGL/Concepts/HalfedgeGraph.h b/BGL/doc/BGL/Concepts/HalfedgeGraph.h index 3769db82e16..a6fc002b0aa 100644 --- a/BGL/doc/BGL/Concepts/HalfedgeGraph.h +++ b/BGL/doc/BGL/Concepts/HalfedgeGraph.h @@ -2,7 +2,7 @@ \ingroup PkgBGLConcepts \cgalConcept -The concept `HalfedgeGraph` is a refinement of the \sc{Bgl} concept +The concept `HalfedgeGraph` is a refinement of the \bgl concept `IncidenceGraph` and adds the notion of a *halfedge*: Each edge is associated with two *opposite* halfedges with source and target vertices swapped. Furthermore, halfedges have a *successor* and *predecessor*, diff --git a/BGL/doc/BGL/NamedParameters.txt b/BGL/doc/BGL/NamedParameters.txt index d0a492fd54a..70a9e8a8029 100644 --- a/BGL/doc/BGL/NamedParameters.txt +++ b/BGL/doc/BGL/NamedParameters.txt @@ -2,7 +2,7 @@ \defgroup bgl_namedparameters Named Parameters \ingroup PkgBGLRef -The algorithms of the Boost Graph Library (\sc{Bgl}) often have many parameters with default +The algorithms of the Boost Graph Library (\bgl) often have many parameters with default values that are appropriate for most cases. In general, when no special treatment is applied, the values of such parameters are passed as a sequence. Deviating from the default for a certain parameter @@ -18,7 +18,7 @@ vertex_descriptor s = vertex(A, g); dijkstra_shortest_paths(g, s, predecessor_map(&p[0]).distance_map(&d[0])); \endcode -In the \sc{Bgl} manual, this is called +In the \bgl manual, this is called named parameters. The named parameters in the snippet use the tags `predecessor_map` and `distance_map` and they are concatenated using the dot operator.
    @@ -26,7 +26,7 @@ and they are concatenated using the dot operator.
    A similar mechanism was introduced in \cgal, with the small difference that the named parameters tag live in the `CGAL::parameters::` namespace and `CGAL::parameters::all_default()` can be used to indicate that default values of optional named parameters must be used. -As in the \sc{BGL}, named parameters in \cgal are also concatenated using +As in the \bgl, named parameters in \cgal are also concatenated using the dot operator, and a typical usage is thus: \code {.cpp} diff --git a/BGL/doc/BGL/PackageDescription.txt b/BGL/doc/BGL/PackageDescription.txt index 8a5d946cd9e..cf7e059049b 100644 --- a/BGL/doc/BGL/PackageDescription.txt +++ b/BGL/doc/BGL/PackageDescription.txt @@ -3,9 +3,9 @@ /*! \defgroup PkgBGLConcepts Concepts \ingroup PkgBGLRef - We extend the Boost Graph Library (\sc{Bgl} for short) with a set of new concepts. + We extend the Boost Graph Library (\bgl for short) with a set of new concepts. In order to make this documentation self-contained we here also document - concepts that are defined in the original version of the \sc{Bgl}. + concepts that are defined in the original version of the \bgl. The documentation of the concepts lists at the same time the functions related to it. Models of the concept and their related functions must be in the same namespace (they will be found by Koenig lookup). @@ -586,9 +586,9 @@ Methods to read and write graphs. \cgalPkgSummaryBegin \cgalPkgAuthors{Andreas Fabri, Fernando Cacciola, Philipp Moeller, and Ron Wein} \cgalPkgDesc{This package provides a framework for interfacing \cgal data structures - with the algorithms of the Boost Graph Library, or \sc{BGL} for short. + with the algorithms of the Boost Graph Library, or \bgl for short. It allows to run graph algorithms directly on \cgal data structures which are model - of the \sc{BGL} graph concepts, for example the shortest path algorithm + of the \bgl graph concepts, for example the shortest path algorithm on a Delaunay triangulation in order to compute the Euclidean minimum spanning tree. Furthermore, it introduces several new graph concepts describing halfedge data structures.} \cgalPkgManuals{Chapter_CGAL_and_the_Boost_Graph_Library,PkgBGLRef} @@ -621,7 +621,7 @@ Methods to read and write graphs. \cgalCRPSection{%CGAL Classes Adapted for the Graph API} -A number of \cgal structures have been adapted as graphs for the \sc{Bgl}. All +A number of \cgal structures have been adapted as graphs for the \bgl. All adapted types are listed here. The pages document which concepts they model, the properties they support, and any possible caveats that a user might encounter. diff --git a/BGL/doc/BGL/graph_traits.txt b/BGL/doc/BGL/graph_traits.txt index 87c96903b6f..d6f87e7b868 100644 --- a/BGL/doc/BGL/graph_traits.txt +++ b/BGL/doc/BGL/graph_traits.txt @@ -3,7 +3,7 @@ \ingroup PkgBGLRef -The \sc{Bgl} defines the class template +The \bgl defines the class template `boost::graph_traits` as a uniform interface to the properties and types of %graph types. @@ -156,7 +156,7 @@ vertex, or walking through the faces container. The mapping between vertices, edges, and faces of the triangulation and the graph is rather straightforward, but there are some subtleties. The -value type of the \sc{Bgl} iterators is the vertex or edge descriptor, +value type of the \bgl iterators is the vertex or edge descriptor, whereas in \cgal all iterators and circulators are also handles and hence have as value type Vertex or Edge. diff --git a/BGL/include/CGAL/boost/graph/selection.h b/BGL/include/CGAL/boost/graph/selection.h index ec8dcd57366..668bc4707e0 100644 --- a/BGL/include/CGAL/boost/graph/selection.h +++ b/BGL/include/CGAL/boost/graph/selection.h @@ -561,6 +561,9 @@ regularize_face_selection_borders( /// \endcond /// \cond SKIP_IN_MANUAL + +namespace experimental { + // TODO: improve and document if useful // // Variant of regularization without graphcut but with brut-force @@ -703,6 +706,8 @@ regularize_face_selection_borders( put(is_selected, fd, true); } } + +} /// \endcond diff --git a/Box_intersection_d/include/CGAL/Box_intersection_d/Box_d.h b/Box_intersection_d/include/CGAL/Box_intersection_d/Box_d.h index 08718db8abd..a6326ed6cae 100644 --- a/Box_intersection_d/include/CGAL/Box_intersection_d/Box_d.h +++ b/Box_intersection_d/include/CGAL/Box_intersection_d/Box_d.h @@ -24,6 +24,7 @@ #include #include +#include namespace CGAL { @@ -63,8 +64,9 @@ class Box_d; template class Box_d< NT_, N, ID_NONE> { protected: - NT_ lo[N]; - NT_ hi[N]; + std::array lo; + std::array hi; + public: typedef NT_ NT; typedef std::size_t ID; @@ -72,8 +74,8 @@ public: Box_d() {} Box_d(bool complete) { init(complete); } Box_d(NT l[N], NT h[N]) { - std::copy( l, l + N, lo ); - std::copy( h, h + N, hi ); + std::copy( l, l + N, &lo[0] ); + std::copy( h, h + N, &hi[0] ); } void init (bool complete = false) { NT inf = box_limits::inf(); diff --git a/Convex_hull_2/include/CGAL/Convex_hull_2/convexity_check_2_impl.h b/Convex_hull_2/include/CGAL/Convex_hull_2/convexity_check_2_impl.h index 2b9d92a8edb..3e5b88d8d6a 100644 --- a/Convex_hull_2/include/CGAL/Convex_hull_2/convexity_check_2_impl.h +++ b/Convex_hull_2/include/CGAL/Convex_hull_2/convexity_check_2_impl.h @@ -18,7 +18,6 @@ #include #include -#include namespace CGAL { @@ -139,8 +138,6 @@ ch_brute_force_check_2(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, const Traits& ch_traits) { - using namespace boost; - typedef typename Traits::Left_turn_2 Left_of_line; ForwardIterator1 iter11; ForwardIterator2 iter21; @@ -165,12 +162,13 @@ ch_brute_force_check_2(ForwardIterator1 first1, ForwardIterator1 last1, while (iter22 != last2) { iter11 = std::find_if( first1, last1, - bind(left_turn, *iter22++, *iter21++, _1) ); + [left_turn, iter22, iter21](const auto& p){ return left_turn(*iter22, *iter21, p); } ); + ++iter22; ++iter21; if (iter11 != last1 ) return false; } iter11 = std::find_if( first1, last1, - bind(left_turn, *first2, *iter21, _1) ); + [left_turn, first2, iter21](const auto& p){ return left_turn(*first2, *iter21, p); } ); if (iter11 != last1 ) return false; return true; } @@ -203,7 +201,8 @@ ch_brute_force_chain_check_2(ForwardIterator1 first1, while (iter22 != last2) { iter11 = std::find_if( first1, last1, - bind(left_turn, *iter22++, *iter21++, _1) ); + [left_turn, iter22, iter21](const auto& p){ return left_turn(*iter22, *iter21, p); } ); + ++iter22; ++iter21; if (iter11 != last1 ) return false; } diff --git a/Distance_2/include/CGAL/squared_distance_2_1.h b/Distance_2/include/CGAL/squared_distance_2_1.h index f9b62838e91..171b8fd1e81 100644 --- a/Distance_2/include/CGAL/squared_distance_2_1.h +++ b/Distance_2/include/CGAL/squared_distance_2_1.h @@ -234,7 +234,7 @@ namespace internal { c2s = CGAL::abs(wcross(seg1.source(), seg1.target(), seg2.source(), k)); c2e = CGAL::abs(wcross(seg1.source(), seg1.target(), seg2.target(), k)); - Comparison_result dm = compare(c2s,c2e); + Comparison_result dm = CGAL::compare(c2s,c2e); if (dm == SMALLER) { return internal::squared_distance(seg2.source(), seg1, k); @@ -249,7 +249,7 @@ namespace internal { } else { c1s = CGAL::abs(wcross(seg2.source(), seg2.target(), seg1.source(), k)); c1e = CGAL::abs(wcross(seg2.source(), seg2.target(), seg1.target(), k)); - Comparison_result dm = compare(c1s,c1e); + Comparison_result dm = CGAL::compare(c1s,c1e); if (crossing2) { if (dm == SMALLER) { return internal::squared_distance(seg1.source(), seg2, k); @@ -272,7 +272,7 @@ namespace internal { c2s = CGAL::abs(wcross(seg1.source(), seg1.target(), seg2.source(), k)); c2e = CGAL::abs(wcross(seg1.source(), seg1.target(), seg2.target(), k)); - dm = compare(c2s,c2e); + dm = CGAL::compare(c2s,c2e); if (dm == EQUAL) // should not happen. return internal::squared_distance_parallel(seg1, seg2, k); diff --git a/Distance_3/include/CGAL/squared_distance_3.h b/Distance_3/include/CGAL/squared_distance_3.h index b805dd8af33..b55542f5e7f 100644 --- a/Distance_3/include/CGAL/squared_distance_3.h +++ b/Distance_3/include/CGAL/squared_distance_3.h @@ -21,5 +21,6 @@ #include #include #include +#include #endif diff --git a/Distance_3/include/CGAL/squared_distance_3_2.h b/Distance_3/include/CGAL/squared_distance_3_2.h index d3d20182a1f..78af20db08f 100644 --- a/Distance_3/include/CGAL/squared_distance_3_2.h +++ b/Distance_3/include/CGAL/squared_distance_3_2.h @@ -225,6 +225,7 @@ squared_distance_to_triangle( const typename K::Point_3 & t0, const typename K::Point_3 & t1, const typename K::Point_3 & t2, + bool & inside, const K& k) { typename K::Construct_vector_3 vector; @@ -239,6 +240,7 @@ squared_distance_to_triangle( && on_left_of_triangle_edge(pt, normal, t2, t0, k)) { // the projection of pt is inside the triangle + inside = true; return squared_distance_to_plane(normal, vector(t0, pt), k); } else { @@ -267,10 +269,12 @@ squared_distance( const K& k) { typename K::Construct_vertex_3 vertex; + bool inside = false; return squared_distance_to_triangle(pt, vertex(t, 0), vertex(t, 1), vertex(t, 2), + inside, k); } diff --git a/Distance_3/include/CGAL/squared_distance_3_3.h b/Distance_3/include/CGAL/squared_distance_3_3.h new file mode 100644 index 00000000000..8f2987a0d5f --- /dev/null +++ b/Distance_3/include/CGAL/squared_distance_3_3.h @@ -0,0 +1,126 @@ +// Copyright (c) 1998-2021 +// Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), +// INRIA Sophia-Antipolis (France), +// Max-Planck-Institute Saarbruecken (Germany), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org) +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Geert-Jan Giezeman, Andreas Fabri + + +#ifndef CGAL_DISTANCE_3_3_H +#define CGAL_DISTANCE_3_3_H + +#include + +#include +#include + +namespace CGAL { + +namespace internal { + +template +inline +typename K::FT +squared_distance(const typename K::Tetrahedron_3 & t, + const typename K::Point_3 & pt, + const K& k) +{ + bool on_bounded_side = true; + const typename K::Point_3 t0 = t[0]; + const typename K::Point_3 t1 = t[1]; + const typename K::Point_3 t2 = t[2]; + const typename K::Point_3 t3 = t[3]; + + bool dmin_initialized = false; + typename K::FT dmin; + bool inside = false; + if(orientation(t0,t1,t2, pt) == NEGATIVE){ + on_bounded_side = false; + dmin = squared_distance_to_triangle(pt, t0, t1, t2, inside, k); + dmin_initialized = true; + if(inside){ + return dmin; + } + } + + if(orientation(t0,t3,t1, pt) == NEGATIVE){ + on_bounded_side = false; + const typename K::FT d = squared_distance_to_triangle(pt, t0, t3, t1, inside, k); + if(inside){ + return d; + } + if(! dmin_initialized){ + dmin = d; + dmin_initialized = true; + }else{ + dmin = (std::min)(d,dmin); + } + } + + if(orientation(t1,t3,t2, pt) == NEGATIVE){ + on_bounded_side = false; + const typename K::FT d = squared_distance_to_triangle(pt, t1, t3, t2, inside, k); + if(inside){ + return d; + } + if(! dmin_initialized){ + dmin = d; + dmin_initialized = true; + }else{ + dmin = (std::min)(d,dmin); + } + } + + if(orientation(t2,t3,t0, pt) == NEGATIVE){ + on_bounded_side = false; + const typename K::FT d = squared_distance_to_triangle(pt, t2, t3, t0, inside, k); + if(inside){ + return d; + } + if(! dmin_initialized){ + dmin = d; + dmin_initialized = true; + }else{ + dmin = (std::min)(d,dmin); + } + } + + if(on_bounded_side){ + return typename K::FT(0); + } + return dmin; +} + +} // namespace internal + + +template +typename K::FT +squared_distance(const Tetrahedron_3 & t, + const Point_3 & pt) +{ + return internal::squared_distance(t,pt,K()); +} + + +template +typename K::FT +squared_distance(const Point_3 & pt, + const Tetrahedron_3 & t) +{ + return internal::squared_distance(t,pt,K()); +} + +} //namespace CGAL + + +#endif diff --git a/Distance_3/test/Distance_3/test_distance_3.cpp b/Distance_3/test/Distance_3/test_distance_3.cpp index 4290da9919c..3a1f72fe786 100644 --- a/Distance_3/test/Distance_3/test_distance_3.cpp +++ b/Distance_3/test/Distance_3/test_distance_3.cpp @@ -56,6 +56,7 @@ struct Test { typedef CGAL::Triangle_3< K > T; typedef CGAL::Plane_3< K > Pl; typedef CGAL::Iso_cuboid_3< K > Cub; + typedef CGAL::Tetrahedron_3< K > Tet; template < typename Type > @@ -109,10 +110,19 @@ struct Test { void P_T() { - std::cout << "Point - Segment\n"; + std::cout << "Point - Triangle\n"; check_squared_distance (p(0, 1, 2), T(p(0, 0, 0), p( 2, 0, 0), p( 0, 2, 0)), 4); } + void P_Tet() + { + std::cout << "Point - Tetrahedron\n"; + check_squared_distance (p(0, 0, 0), Tet(p(0, 0, 0), p( 1, 0, 0), p( 0, 1, 0), p( 0, 0, 1)), 0); + check_squared_distance (p(0, 0, 2), Tet(p(0, 0, 0), p( 1, 0, 0), p( 0, 1, 0), p( 0, 0, 1)), 1); + check_squared_distance (p(0, 0, -1), Tet(p(0, 0, 0), p( 1, 0, 0), p( 0, 1, 0), p( 0, 0, 1)), 1); + check_squared_distance (p(5, 0, 0), Tet(p(0, 0, 0), p( 1, 0, 0), p( 0, 1, 0), p( 4, 0, 1)), 2); + } + void S_S() { std::cout << "Segment - Segment\n"; @@ -238,6 +248,7 @@ struct Test { P_P(); P_S(); P_T(); + P_Tet(); S_S(); P_R(); R_R(); diff --git a/Documentation/doc/CMakeLists.txt b/Documentation/doc/CMakeLists.txt index 94fc5649ef8..00d20d34bae 100644 --- a/Documentation/doc/CMakeLists.txt +++ b/Documentation/doc/CMakeLists.txt @@ -27,7 +27,7 @@ else() endif() find_package(Doxygen) -find_package(PythonInterp 2.6.7) +find_package(PythonInterp) if(NOT DOXYGEN_FOUND) message(WARNING "Cannot build the documentation without Doxygen!") diff --git a/Documentation/doc/Documentation/Developer_manual/Chapter_debugging.txt b/Documentation/doc/Documentation/Developer_manual/Chapter_debugging.txt index e6a586b59af..3415b457cec 100644 --- a/Documentation/doc/Documentation/Developer_manual/Chapter_debugging.txt +++ b/Documentation/doc/Documentation/Developer_manual/Chapter_debugging.txt @@ -101,7 +101,7 @@ named `Traits1` and `Traits2`, and a third parameter named other is (presumably) a traits class that always gives the right answer. The `Adapter` is needed since the `X_curve` types for `Traits1` and `Traits2` might be different. -This cross-checker does nothing other then asserting that the two traits +This cross-checker does nothing other than asserting that the two traits classes return the same values by calling the the counterparts in the member traits classes (`tr1`,`tr2`) and comparing the results. diff --git a/Documentation/doc/Documentation/Developer_manual/cmakelist_script.txt b/Documentation/doc/Documentation/Developer_manual/cmakelist_script.txt index 60af5578426..64ce1695e41 100644 --- a/Documentation/doc/Documentation/Developer_manual/cmakelist_script.txt +++ b/Documentation/doc/Documentation/Developer_manual/cmakelist_script.txt @@ -26,7 +26,7 @@ source file. libraries (i.e.\ "Core", "ImageIO", and "Qt5"). An example is `-c Core`.
    `-b boost1:boost2:...`
    Lists components ("boost1", -"boost2") of \sc{Boost} to which the executable(s) should be +"boost2") of \boost to which the executable(s) should be linked. Valid options are, for instance, "filesystem" or "program_options". diff --git a/Documentation/doc/Documentation/Third_party.txt b/Documentation/doc/Documentation/Third_party.txt index 57422452984..a7232b3b1af 100644 --- a/Documentation/doc/Documentation/Third_party.txt +++ b/Documentation/doc/Documentation/Third_party.txt @@ -11,11 +11,11 @@ supporting C++14 or later. | Operating System | Compiler | | :------- | :--------------- | -| Linux | \sc{Gnu} `g++` 6.3 or later\cgalFootnote{`http://gcc.gnu.org/`} | +| Linux | \gnu `g++` 6.3 or later\cgalFootnote{`http://gcc.gnu.org/`} | | | `Clang` \cgalFootnote{`http://clang.llvm.org/`} compiler version 8.0.0 | -| \sc{MS} Windows | \sc{Gnu} `g++` 6.3 or later\cgalFootnote{`http://gcc.gnu.org/`} | -| | \sc{MS} Visual `C++` 14.0, 15.9, 16.0 (\sc{Visual Studio} 2015, 2017, and 2019)\cgalFootnote{`https://visualstudio.microsoft.com/`} | -| MacOS X | \sc{Gnu} `g++` 6.3 or later\cgalFootnote{`http://gcc.gnu.org/`} | +| \ms Windows | \gnu `g++` 6.3 or later\cgalFootnote{`http://gcc.gnu.org/`} | +| | \ms Visual `C++` 14.0, 15.9, 16.0 (\visualstudio 2015, 2017, and 2019)\cgalFootnote{`https://visualstudio.microsoft.com/`} | +| MacOS X | \gnu `g++` 6.3 or later\cgalFootnote{`http://gcc.gnu.org/`} | | | Apple `Clang` compiler versions 7.0.2 and 10.0.1 | @@ -58,38 +58,38 @@ The \stl comes with the compiler, and as such no installation is required. \subsection thirdpartyBoost Boost Version 1.66 or later -The \sc{Boost} libraries are a set of portable C++ source libraries. -Most of \sc{Boost} libraries are header-only, but a few of them need to be compiled or +The \boost libraries are a set of portable C++ source libraries. +Most of \boost libraries are header-only, but a few of them need to be compiled or installed as binaries. -\cgal only requires the headers of the \sc{Boost} libraries, but some demos and examples +\cgal only requires the headers of the \boost libraries, but some demos and examples depend on the binary library `Boost.Program_options`. -In case the \sc{Boost} libraries are not installed on your system already, you +In case the \boost libraries are not installed on your system already, you can obtain them from `https://www.boost.org/`. For Visual C++ you can download precompiled libraries from `https://sourceforge.net/projects/boost/files/boost-binaries/`. -As there is no canonical directory for where to find \sc{Boost} on Windows, +As there is no canonical directory for where to find \boost on Windows, we recommend that you define the environment variable -`BOOST_ROOT` and set it to where you have installed \sc{Boost}, e.g., `C:\boost\boost_1_69_0`. +`BOOST_ROOT` and set it to where you have installed \boost, e.g., `C:\boost\boost_1_69_0`. \subsection thirdpartyMPFR GNU Multiple Precision Arithmetic (GMP) and GNU Multiple Precision Floating-Point Reliably (MPFR) Libraries GMP Version 4.2 or later, MPFR Version 2.2.1 or later The components `libCGAL`, `libCGAL_Core`, and `libCGAL_Qt5` require -\sc{Gmp} and \sc{Mpfr} which are libraries for multi precision integers and rational numbers, +\gmp and \mpfr which are libraries for multi precision integers and rational numbers, and for multi precision floating point numbers. \cgal combines floating point arithmetic with exact arithmetic in order to be efficient and reliable. \cgal has a built-in -number type for that, but \sc{Gmp} and \sc{Mpfr} provide a faster +number type for that, but \gmp and \mpfr provide a faster solution, and we recommend to use them. These libraries can be obtained from `https://gmplib.org/` and `https://www.mpfr.org/`. -Since Visual \cpp is not properly supported by the \sc{Gmp} and \sc{Mpfr} projects, -we provide precompiled versions of \sc{Gmp} and \sc{Mpfr}, which can be downloaded with the installer +Since Visual \cpp is not properly supported by the \gmp and \mpfr projects, +we provide precompiled versions of \gmp and \mpfr, which can be downloaded with the installer `CGAL-\cgalReleaseNumber``-Setup.exe`. \section secoptional3rdpartysoftware Optional Third Party Libraries @@ -108,51 +108,51 @@ the location of third-party software during configuration. Qt is a cross-platform application and UI framework. The component libCGAL_Qt5 is essential to run the \cgal demos and basic viewers. -It requires \sc{Qt}5 installed on your system. -In case \sc{Qt} is not yet installed on your system, you can download +It requires \qt5 installed on your system. +In case \qt is not yet installed on your system, you can download it from `https://www.qt-project.org/`. -The exhaustive list of \sc{Qt}5 components used in demos is: +The exhaustive list of \qt5 components used in demos is: `Core`, `Gui`, `Help`, `OpenGL`, `Script`, `ScriptTools`, `Svg`, `Widgets`, `qcollectiongenerator` (with `sqlite` driver plugin), and `Xml`. \subsection thirdpartyEigen Eigen Version 3.1 or later -\sc{Eigen} is a `C++` template library for linear algebra. \sc{Eigen} supports all +\eigen is a `C++` template library for linear algebra. \eigen supports all matrix sizes, various matrix decomposition methods and sparse linear solvers. -In \cgal, \sc{Eigen} is used in many packages such as \ref +In \cgal, \eigen is used in many packages such as \ref PkgPoissonSurfaceReconstruction3 or \ref PkgJetFitting3, providing sparse linear solvers and singular value decompositions. A package -dependency over \sc{Eigen} is marked on the Package Overview page. In order to use Eigen in \cgal programs, the executables should be linked with the CMake imported target `CGAL::Eigen3_support` provided in `CGAL_Eigen3_support.cmake`. -The \sc{Eigen} web site is `http://eigen.tuxfamily.org`. +The \eigen web site is `http://eigen.tuxfamily.org`. \subsection thirdpartyOpenGR OpenGR -\sc{OpenGR} is a set C++ libraries for 3D Global Registration released under the terms of the APACHE V2 licence. +\opengr is a set C++ libraries for 3D Global Registration released under the terms of the APACHE V2 licence. -\cgal provides wrappers for the Super4PCS algorithm of \sc{OpenGR} in the \ref PkgPointSetProcessing3Ref -packages. In order to use \sc{OpenGR} in \cgal programs, the executables should be linked with the CMake imported target `CGAL::OpenGR_support` provided in `CGAL_OpenGR_support.cmake`. +\cgal provides wrappers for the Super4PCS algorithm of \opengr in the \ref PkgPointSetProcessing3Ref +packages. In order to use \opengr in \cgal programs, the executables should be linked with the CMake imported target `CGAL::OpenGR_support` provided in `CGAL_OpenGR_support.cmake`. -The \sc{OpenGR} web site is `https://github.com/STORM-IRIT/OpenGR`. +The \opengr web site is `https://github.com/STORM-IRIT/OpenGR`. \subsection thirdpartylibpointmatcher PointMatcher -\sc{libpointmatcher} is a modular library implementing the Iterative Closest Point (ICP) algorithm for aligning point clouds, released under a permissive BSD license. +\libpointmatcher is a modular library implementing the Iterative Closest Point (ICP) algorithm for aligning point clouds, released under a permissive BSD license. -\cgal provides wrappers for the ICP algorithm of \sc{libpointmatcher} in the \ref PkgPointSetProcessing3Ref -packages. In order to use \sc{libpointmatcher} in \cgal programs, the +\cgal provides wrappers for the ICP algorithm of \libpointmatcher in the \ref PkgPointSetProcessing3Ref +packages. In order to use \libpointmatcher in \cgal programs, the executables should be linked with the CMake imported target `CGAL::pointmatcher_support` provided in `CGAL_pointmatcher_support.cmake`. -The \sc{libpointmatcher} web site is `https://github.com/ethz-asl/libpointmatcher`. \attention On Windows, we only support version 1.3.1 of PointMatcher with version 3.3.7 of Eigen, with some changes to the recipe at `https://github.com/ethz-asl/libpointmatcher/blob/master/doc/CompilationWindows.md`:`NABO_INCLUDE_DIR` becomes `libnabo_INCLUDE_DIRS` @@ -163,104 +163,104 @@ and `NABO_LIBRARY` becomes `libnabo_LIBRARIES` in the "Build libpointmatcher" se Version 6.2 or later \leda is a library of efficient data structures and -algorithms. Like \sc{Core}, \leda offers a real number data type. +algorithms. Like \core, \leda offers a real number data type. In \cgal this library is optional, and its number types can -be used as an alternative to \sc{Gmp}, \sc{Mpfr}, and \sc{Core}. +be used as an alternative to \gmp, \mpfr, and \core. Free and commercial editions of \leda are available from `https://www.algorithmic-solutions.com`. \subsection thirdpartyMPFI Multiple Precision Floating-point Interval (MPFI) Version 1.4 or later -\sc{Mpfi} provides arbitrary precision interval arithmetic with intervals -represented using \sc{Mpfr} reliable floating-point numbers. -It is based on the libraries \sc{Gmp} and \sc{Mpfr}. +\mpfi provides arbitrary precision interval arithmetic with intervals +represented using \mpfr reliable floating-point numbers. +It is based on the libraries \gmp and \mpfr. In the setting of \cgal, this library is optional: it is used by some models of the \ref PkgAlgebraicKernelD "Algebraic Kernel". -\sc{Mpfi} can be downloaded from `https://mpfi.gforge.inria.fr/`. +\mpfi can be downloaded from `https://mpfi.gforge.inria.fr/`. \subsection thirdpartyRS3 RS and RS3 -\sc{Rs} (Real Solutions) is devoted to the study of the real roots of +\rs (Real Solutions) is devoted to the study of the real roots of polynomial systems with a finite number of complex roots (including -univariate polynomials). In \cgal, \sc{Rs} is used by one model of the +univariate polynomials). In \cgal, \rs is used by one model of the \ref PkgAlgebraicKernelD "Algebraic Kernel". -\sc{Rs} is freely distributable for non-commercial use. You can download it -from `http://vegas.loria.fr/rs/`. Actually, the \sc{Rs} package also includes \sc{Rs3}, the -successor of \sc{Rs}, which is used in conjunction with it. +\rs is freely distributable for non-commercial use. You can download it +from `http://vegas.loria.fr/rs/`. Actually, the \rs package also includes \rs3, the +successor of \rs, which is used in conjunction with it. -The libraries \sc{Rs} and \sc{Rs3} need \sc{Mpfi}, which can be downloaded from +The libraries \rs and \rs3 need \mpfi, which can be downloaded from `https://mpfi.gforge.inria.fr/`. \subsection thirdpartyNTL NTL Version 5.1 or later -\sc{Ntl} provides data structures and algorithms for signed, arbitrary +\ntl provides data structures and algorithms for signed, arbitrary length integers, and for vectors, matrices, and polynomials over the -integers and over finite fields. The optional library \sc{Ntl} is used by \cgal -to speed up operations of the Polynomial package, such as GCDs. It is recommended to install \sc{Ntl} with support from \sc{Gmp}. +integers and over finite fields. The optional library \ntl is used by \cgal +to speed up operations of the Polynomial package, such as GCDs. It is recommended to install \ntl with support from \gmp. -\sc{Ntl} can be downloaded from `https://www.shoup.net/ntl/`. +\ntl can be downloaded from `https://www.shoup.net/ntl/`. \subsection thirdpartyESBTL ESBTL -The \sc{Esbtl} (Easy Structural Biology Template Library) is a library that allows -the handling of \sc{Pdb} data. +The \esbtl (Easy Structural Biology Template Library) is a library that allows +the handling of \pdb data. -In \cgal, the \sc{Esbtl} is used in an example of the \ref PkgSkinSurface3 package. +In \cgal, the \esbtl is used in an example of the \ref PkgSkinSurface3 package. It can be downloaded from `http://esbtl.sourceforge.net/`. \subsection thirdpartyTBB Intel TBB -\sc{Tbb} (Threading Building Blocks) is a library developed by Intel Corporation for writing software +\tbb (Threading Building Blocks) is a library developed by Intel Corporation for writing software programs that take advantage of multi-core processors. -In \cgal, \sc{Tbb} is used by the packages that offer parallel -code. In order to use \sc{Tbb} in \cgal programs, the executables +In \cgal, \tbb is used by the packages that offer parallel +code. In order to use \tbb in \cgal programs, the executables should be linked with the CMake imported target `CGAL::TBB_support` provided in `CGAL_TBB_support.cmake`. -The \sc{Tbb} web site is `https://www.threadingbuildingblocks.org`. +The \tbb web site is `https://www.threadingbuildingblocks.org`. \subsection thirdpartyLASlib LASlib -\sc{LASlib} is a `C++` library for handling LIDAR data sets stored in +\laslib is a `C++` library for handling LIDAR data sets stored in the LAS format (or the compressed LAZ format). -In \cgal, \sc{LASlib} is used to provide input and output functions in -the \ref PkgPointSetProcessing3 package. In order to use \sc{LASlib} +In \cgal, \laslib is used to provide input and output functions in +the \ref PkgPointSetProcessing3 package. In order to use \laslib in \cgal programs, the executables should be linked with the CMake imported target `CGAL::LASLIB_support` provided in `CGAL_LASLIB_support.cmake`. -The \sc{LASlib} web site is `https://rapidlasso.com/lastools/`. \sc{LASlib} +The \laslib web site is `https://rapidlasso.com/lastools/`. \laslib is usually distributed along with LAStools: for simplicity, \cgal provides a fork with a CMake based install procedure. \subsection thirdpartyOpenCV OpenCV -\sc{OpenCV} (Open Computer Vision) is a library designed for computer +\opencv (Open Computer Vision) is a library designed for computer vision, computer graphics and machine learning. -In \cgal, \sc{OpenCV} is used by the \ref PkgClassification -package. In order to use \sc{OpenCV} in \cgal programs, the +In \cgal, \opencv is used by the \ref PkgClassification +package. In order to use \opencv in \cgal programs, the executables should be linked with the CMake imported target `CGAL::OpenCV_support` provided in `CGAL_OpenCV_support.cmake`. -The \sc{OpenCV} web site is `https://opencv.org/`. +The \opencv web site is `https://opencv.org/`. \subsection thirdpartyTensorFlow TensorFlow -\sc{TensorFlow} is a library designed for machine learning and deep learning. +\tensorflow is a library designed for machine learning and deep learning. -In \cgal, the C++ API of \sc{TensorFlow} is used by the \ref +In \cgal, the C++ API of \tensorflow is used by the \ref PkgClassification package for neural network. The C++ API can be compiled using CMake: it is distributed as part of the official package and is located in `tensorflow/contrib/cmake`. Be sure to @@ -270,20 +270,20 @@ enable and compile the following targets: - `tensorflow_BUILD_PYTHON_BINDINGS` - `tensorflow_BUILD_SHARED_LIB`. -In order to use \sc{TensorFlow} in \cgal programs, the executables +In order to use \tensorflow in \cgal programs, the executables should be linked with the CMake imported target `CGAL::TensorFlow_support` provided in `CGAL_TensorFlow_support.cmake`. -The \sc{TensorFlow} web site is `https://www.tensorflow.org/`. +The \tensorflow web site is `https://www.tensorflow.org/`. \subsection thirdpartyMETIS METIS Version 5.1 or later -\sc{METIS} is a library developed by the Karypis Lab +\metis is a library developed by the Karypis Lab and designed to partition graphs and produce fill-reducing matrix orderings. -\cgal offers wrappers around some of the methods of the \sc{METIS} library +\cgal offers wrappers around some of the methods of the \metis library to allow the partitioning of graphs that are models of the concepts of the Boost Graph Library, and, by extension, of surface meshes (see Section \ref BGLPartitioning of the package \ref PkgBGL). @@ -293,7 +293,7 @@ at `http://glaro \subsection thirdpartyzlib zlib -\sc{zlib} is a data compression library, and is essential for the component libCGAL_ImageIO. +\zlib is a data compression library, and is essential for the component libCGAL_ImageIO. In \cgal, this library is used in the examples of the \ref PkgSurfaceMesher3 package. @@ -302,9 +302,9 @@ for instance, on Windows, you can download it from `ceres-solver.org` @@ -312,26 +312,26 @@ for more information. \subsection thirdpartyGLPK GLPK -\sc{GLPK} (GNU Linear Programming Kit) is a library for solving linear programming (LP), mixed integer programming (MIP), and other related problems. +\glpk (GNU Linear Programming Kit) is a library for solving linear programming (LP), mixed integer programming (MIP), and other related problems. -In \cgal, \sc{GLPK} provides an optional linear integer program solver +In \cgal, \glpk provides an optional linear integer program solver in the \ref PkgPolygonalSurfaceReconstruction package. In order to use -\sc{GLPK} in \cgal programs, the executables should be linked with the +\glpk in \cgal programs, the executables should be linked with the CMake imported target `CGAL::GLPK_support` provided in `CGAL_GLPK_support.cmake`. -The \sc{GLPK} web site is `https://www.gnu.org/software/glpk/`. +The \glpk web site is `https://www.gnu.org/software/glpk/`. \subsection thirdpartySCIP SCIP -\sc{SCIP} (Solving Constraint Integer Programs) is currently one of the fastest open source solvers for mixed integer programming (MIP) and mixed integer nonlinear programming (MINLP). +\scip (Solving Constraint Integer Programs) is currently one of the fastest open source solvers for mixed integer programming (MIP) and mixed integer nonlinear programming (MINLP). -In \cgal, \sc{SCIP} provides an optional linear integer program solver +In \cgal, \scip provides an optional linear integer program solver in the \ref PkgPolygonalSurfaceReconstruction package. In order to use -\sc{SCIP} in \cgal programs, the executables should be linked with the +\scip in \cgal programs, the executables should be linked with the CMake imported target `CGAL::SCIP_support` provided in `CGAL_SCIP_support.cmake`. -The \sc{SCIP} web site is `http://scip.zib.de/`. +The \scip web site is `http://scip.zib.de/`. */ diff --git a/Documentation/doc/Documentation/Tutorials/Tutorial_GIS.txt b/Documentation/doc/Documentation/Tutorials/Tutorial_GIS.txt index 255f39a5f5c..9ac43d3eb53 100644 --- a/Documentation/doc/Documentation/Tutorials/Tutorial_GIS.txt +++ b/Documentation/doc/Documentation/Tutorials/Tutorial_GIS.txt @@ -276,7 +276,7 @@ classifier currently available in \cgal is the %random forest from ETHZ. As it is a supervised classifier, a training set is needed. The following snippet shows how to use some manually selected training -set to train a %fandom rorest classifier and compute a classification +set to train a %random forest classifier and compute a classification regularized by a graph cut algorithm: \snippet Classification/gis_tutorial_example.cpp Classification diff --git a/Documentation/doc/Documentation/Usage.txt b/Documentation/doc/Documentation/Usage.txt index eba087fdaa6..ae504aecf7c 100644 --- a/Documentation/doc/Documentation/Usage.txt +++ b/Documentation/doc/Documentation/Usage.txt @@ -83,9 +83,9 @@ contains the following subdirectories: | Directory | Contents | | :------------------------- | :----------| -| `auxiliary` (Windows only) | precompiled \sc{Gmp} and \sc{Mpfr} for Windows | +| `auxiliary` (Windows only) | precompiled \gmp and \mpfr for Windows | | `cmake/modules` | modules for finding and using libraries | -| `demo` | demo programs (most of them need \sc{Qt}, geomview or other third-party products) | +| `demo` | demo programs (most of them need \qt, geomview or other third-party products) | | `doc_html` | documentation (HTML) | | `examples` | example programs | | `include` | header files | @@ -94,13 +94,13 @@ contains the following subdirectories: The directories `include/CGAL/CORE` and `src/CGALCore` contain a distribution of the Core library version 1.7 for -dealing with algebraic numbers. Note that \sc{Core} is not part of \cgal and has its +dealing with algebraic numbers. Note that \core is not part of \cgal and has its own license. The directory `include/CGAL/OpenNL` contains a distribution of the Open Numerical Library, which provides solvers for sparse linear systems, especially designed for the Computer Graphics community. -\sc{OpenNL} is not part of \cgal and has its own license. +\opennl is not part of \cgal and has its own license. The only documentation shipped within \cgal sources is the present manual. The \cgal manual can also be accessed online at @@ -123,7 +123,7 @@ a standard location (such as `/usr/local/include`): For more advanced installations, we refer to Section \ref installation_configwithcmake. Note that even though \cgal is a header-only library, not all its dependencies -are header-only. The libraries \sc{Gmp} and \sc{Mpfr}, for example, are not +are header-only. The libraries \gmp and \mpfr, for example, are not header-only. As such, these dependencies must be built or installed independently. \section usage_configuring Configuring your Program @@ -235,7 +235,7 @@ The results of a successful configuration are build files that control the build The nature of the build files depends on the generator used during configuration, but in most cases they contain several targets, such as all the examples of the Triangulation_2 package. -In a \sc{Unix}-like environment the default generator produces makefiles. +In a \unix-like environment the default generator produces makefiles. You can use the `make` command-line tool for the succeeding build step as follows: cd CGAL-\cgalReleaseNumber/examples/Triangulation_2 diff --git a/Documentation/doc/Documentation/advanced/Configuration_variables.txt b/Documentation/doc/Documentation/advanced/Configuration_variables.txt index 2a880f1e488..191bb353d59 100644 --- a/Documentation/doc/Documentation/advanced/Configuration_variables.txt +++ b/Documentation/doc/Documentation/advanced/Configuration_variables.txt @@ -103,30 +103,30 @@ other but never both. \subsection installation_boost Boost Libraries -In most cases, if \sc{Boost} is not automatically found, setting the `BOOST_ROOT` +In most cases, if \boost is not automatically found, setting the `BOOST_ROOT` variable is enough. If it is not, you can specify the header and library directories individually. You can also provide the full pathname to a specific compiled library if it cannot be found in the library directory or its name is non-standard. -By default, when \sc{Boost} binary libraries are needed, the shared versions +By default, when \boost binary libraries are needed, the shared versions are used if present. You can set the variable `CGAL_Boost_USE_STATIC_LIBS` to `ON` if you want to link with static versions explicitly. -On Windows, if you link with \sc{Boost} shared libraries, you must ensure that +On Windows, if you link with \boost shared libraries, you must ensure that the `.dll` files are found by the dynamic linker, at run time. -For example, you can add the path to the \sc{Boost} `.dll` to the +For example, you can add the path to the \boost `.dll` to the `PATH` environment variable. | Variable | Description | Type | | :- | :- | :- | -| `BOOST_ROOT`\cgalFootnote{The environment variable can be spelled either `BOOST_ROOT` or `BOOSTROOT`} | Root directory of your \sc{Boost} installation | Either CMake or Environment | +| `BOOST_ROOT`\cgalFootnote{The environment variable can be spelled either `BOOST_ROOT` or `BOOSTROOT`} | Root directory of your \boost installation | Either CMake or Environment | | `Boost_INCLUDE_DIR` | Directory containing the `boost/version.hpp` file | CMake | | `BOOST_INCLUDEDIR` | Idem | Environment | -| `Boost_LIBRARY_DIRS` | Directory containing the compiled \sc{Boost} libraries | CMake | +| `Boost_LIBRARY_DIRS` | Directory containing the compiled \boost libraries | CMake | | `BOOST_LIBRARYDIR` | Idem | Environment | -| `Boost_(xyz)_LIBRARY_RELEASE` | Full pathname to a release build of the compiled 'xyz' \sc{Boost} library | CMake | -| `Boost_(xyz)_LIBRARY_DEBUG` | Full pathname to a debug build of the compiled 'xyz' \sc{Boost} library | CMake | +| `Boost_(xyz)_LIBRARY_RELEASE` | Full pathname to a release build of the compiled 'xyz' \boost library | CMake | +| `Boost_(xyz)_LIBRARY_DEBUG` | Full pathname to a debug build of the compiled 'xyz' \boost library | CMake | \subsection installation_gmp GMP and MPFR Libraries @@ -136,42 +136,42 @@ containing the libraries is needed and you would specify `GMP|MPFR_LIBRARY_DIR` `GMP|MPFR_LIBRARIES`. On the other hand, under Linux the actual library filename is needed. Thus you would specify `GMP|MPFR_LIBRARIES`. In no case you need to specify both. -\cgal uses both \sc{Gmp} and \sc{Mpfr} so both need to be supported. If either of them is unavailable the -usage of \sc{Gmp} and of \sc{Mpfr} will be disabled. +\cgal uses both \gmp and \mpfr so both need to be supported. If either of them is unavailable the +usage of \gmp and of \mpfr will be disabled. | Variable | Description | Type | | :- | :- | :- | -| `CGAL_DISABLE_GMP` | Indicates whether to search and use \sc{Gmp}/\sc{Mpfr} or not | CMake | -| `GMP_DIR` | Directory of \sc{Gmp} default installation | Environment | +| `CGAL_DISABLE_GMP` | Indicates whether to search and use \gmp/\mpfr or not | CMake | +| `GMP_DIR` | Directory of \gmp default installation | Environment | | `GMP_INCLUDE_DIR` | Directory containing the `gmp.h` file | CMake | | `GMP_INC_DIR` | Idem | Environment | -| `GMP_LIBRARIES_DIR` | Directory containing the compiled \sc{Gmp} library | CMake | +| `GMP_LIBRARIES_DIR` | Directory containing the compiled \gmp library | CMake | | `GMP_LIB_DIR` | Idem | Environment | -| `GMP_LIBRARIES` | Full pathname of the compiled \sc{Gmp} library | CMake | +| `GMP_LIBRARIES` | Full pathname of the compiled \gmp library | CMake | | `MPFR_INCLUDE_DIR` | Directory containing the `mpfr.h` file | CMake | | `MPFR_INC_DIR` | Idem | Environment | -| `MPFR_LIBRARIES_DIR` | Directory containing the compiled \sc{Mpfr} library | CMake | +| `MPFR_LIBRARIES_DIR` | Directory containing the compiled \mpfr library | CMake | | `MPFR_LIB_DIR` | Idem | Environment | -| `MPFR_LIBRARIES` | Full pathname of the compiled \sc{Mpfr} library | CMake | +| `MPFR_LIBRARIES` | Full pathname of the compiled \mpfr library | CMake | -Under Linux, the \sc{Gmpxx} is also searched for, and you may specify the following variables: +Under Linux, the \gmpxx is also searched for, and you may specify the following variables: | Variable | Description | Type | | :- | :- | :- | -| `GMPXX_DIR` | Directory of \sc{gmpxx} default installation | Environment | +| `GMPXX_DIR` | Directory of \gmpxx default installation | Environment | | `GMPXX_INCLUDE_DIR` | Directory containing the `gmpxx.h` file | CMake | -| `GMPXX_LIBRARIES` | Full pathname of the compiled \sc{Gmpxx} library | CMake | +| `GMPXX_LIBRARIES` | Full pathname of the compiled \gmpxx library | CMake | \subsection installation_qt5 Qt5 Library You must set the cmake or environment variable `Qt5_DIR` to point to the path -to the directory containing the file `Qt5Config.cmake` created by your \sc{Qt}5 installation. If you are +to the directory containing the file `Qt5Config.cmake` created by your \qt5 installation. If you are using the open source edition it should be `/qt-everywhere-opensource-src-/qtbase/lib/cmake/Qt5`. \subsection installation_leda LEDA Library @@ -188,7 +188,7 @@ The variables specifying definitions and flags can be left undefined if they are | Variable | Description | Type | | :- | :- | :- | | `WITH_LEDA` | Indicates whether to search and use \leda or not | CMake | -| `LEDA_DIR` | Directory of \sc{LEDA} default installation | Environment | +| `LEDA_DIR` | Directory of \leda default installation | Environment | | `LEDA_INCLUDE_DIR` | Directory containing the file `LEDA/system/basic.h` | CMake | | `LEDA_LIBRARIES` | Directory containing the compiled \leda libraries | CMake | | `LEDA_INC_DIR` | Directory containing the file `LEDA/system/basic.h` | Environment | @@ -203,21 +203,21 @@ The variables specifying definitions and flags can be left undefined if they are \subsection installation_mpfi MPFI Library \cgal provides a number type based on this library, but the \cgal library -itself does not depend on \sc{Mpfi}. This means that this library must be +itself does not depend on \mpfi. This means that this library must be configured when compiling an application that uses the above number type. -When \sc{Mpfi} files are not on the standard path, the locations of the headers +When \mpfi files are not on the standard path, the locations of the headers and library files must be specified by using environment variables. | Variable | Description | Type | | :- | :- | :- | -| `MPFI_DIR` |Directory of \sc{MPFI} default installation | Environment | +| `MPFI_DIR` |Directory of \mpfi default installation | Environment | | `MPFI_INCLUDE_DIR` | Directory containing the `mpfi.h` file | CMake | | `MPFI_INC_DIR` | Idem | Environment | -| `MPFI_LIBRARIES_DIR` | Directory containing the compiled \sc{Mpfi} library | CMake | +| `MPFI_LIBRARIES_DIR` | Directory containing the compiled \mpfi library | CMake | | `MPFI_LIB_DIR` | Idem | Environment | -| `MPFI_LIBRARIES` | Full pathname of the compiled \sc{Mpfi} library | CMake | +| `MPFI_LIBRARIES` | Full pathname of the compiled \mpfi library | CMake | @@ -231,55 +231,55 @@ CMake will try to find Rs in the standard header and library directories. When it is not automatically detected, the locations of the headers and library files must be specified using environment variables. -Rs needs \sc{Gmp} 4.2 or later and \sc{Mpfi} 1.3.4 or later. The variables +Rs needs \gmp 4.2 or later and \mpfi 1.3.4 or later. The variables related to the latter library may also need to be defined. | Variable | Description | Type | | :- | :- | :- | -| `RS_DIR` | Directory of \sc{Rs} default installation | Environment | +| `RS_DIR` | Directory of \rs default installation | Environment | | `RS_INCLUDE_DIR` | Directory containing the `rs_exports.h` file | CMake | | `RS_INC_DIR` | Idem | Environment | -| `RS_LIBRARIES_DIR` | Directory containing the compiled \sc{Rs} library | CMake | +| `RS_LIBRARIES_DIR` | Directory containing the compiled \rs library | CMake | | `RS_LIB_DIR` | Idem | Environment | -| `RS_LIBRARIES` | Full pathname of the compiled \sc{Rs} library | CMake | +| `RS_LIBRARIES` | Full pathname of the compiled \rs library | CMake | -Similar variables exist for \sc{Rs3}. +Similar variables exist for \rs3. | Variable | Description | Type | | :- | :- | :- -| `RS3_DIR` | Directory of \sc{Rs3} default installation | Environment | +| `RS3_DIR` | Directory of \rs3 default installation | Environment | | `RS3_INCLUDE_DIR` | Directory containing the file `rs3_fncts.h` file | CMake | | `RS3_INC_DIR` | Idem | Environment | -| `RS3_LIBRARIES_DIR` | Directory containing the compiled \sc{Rs3} library | CMake | +| `RS3_LIBRARIES_DIR` | Directory containing the compiled \rs3 library | CMake | | `RS3_LIB_DIR` | Idem | Environment | -| `RS3_LIBRARIES` | Full pathname of the compiled \sc{Rs3} library | CMake | +| `RS3_LIBRARIES` | Full pathname of the compiled \rs3 library | CMake | \subsection installation_ntl NTL Library Some polynomial computations in \cgal's algebraic kernel -are speed up when \sc{Ntl} is available. +are speed up when \ntl is available. As the algebraic kernel is not compiled as a part of the \cgal library, this library is not detected nor configured at installation time. -CMake will try to find \sc{Ntl} in the standard header and library +CMake will try to find \ntl in the standard header and library directories. When it is not automatically detected, the locations of the headers and library files must be specified using environment variables. | Variable | Description | Type | | :- | :- | :- | -| `NTL_DIR` | Directory of \sc{NTL} default installation | Environment | +| `NTL_DIR` | Directory of \ntl default installation | Environment | | `NTL_INCLUDE_DIR` | Directory containing the `NTL/ZZX.h` file | CMake | | `NTL_INC_DIR` | Idem | Environment | -| `NTL_LIBRARIES_DIR` | Directory containing the compiled \sc{Ntl} library | CMake | +| `NTL_LIBRARIES_DIR` | Directory containing the compiled \ntl library | CMake | | `NTL_LIB_DIR` | Idem | Environment | -| `NTL_LIBRARIES` | Full pathname of the compiled \sc{Ntl} library | CMake | +| `NTL_LIBRARIES` | Full pathname of the compiled \ntl library | CMake | \subsection installation_eigen Eigen Library -\sc{Eigen} is a header-only template library. -Only the directory containing the header files of \sc{Eigen} 3.1 (or greater) is needed. +\eigen is a header-only template library. +Only the directory containing the header files of \eigen 3.1 (or greater) is needed. | Variable | Description | Type | @@ -289,35 +289,35 @@ Only the directory containing the header files of \sc{Eigen} 3.1 (or grea \subsection installation_esbtl ESBTL Library -One skin surface example requires the \sc{Esbtl} library in order to read \sc{Pdb} files. +One skin surface example requires the \esbtl library in order to read \pdb files. -If \sc{Esbtl} is not automatically found, setting the `ESBTL_INC_DIR` +If \esbtl is not automatically found, setting the `ESBTL_INC_DIR` environment variable is sufficient. | Variable | Description | Type | | :- | :- | :- | -| `ESBTL_DIR` | Directory of \sc{ESBTL} default installation | Environment | +| `ESBTL_DIR` | Directory of \esbtl default installation | Environment | | `ESBTL_INC_DIR` | Directory containing the `ESBTL/default.h` file | Environment | | `ESBTL_INCLUDE_DIR` | Directory containing the `ESBTL/default.h` file | CMake | \subsection installation_metis METIS Library -Some BGL examples require the \sc{Metis} library in order to partition \sc{Metis} meshes. +Some BGL examples require the \metis library in order to partition \metis meshes. -If \sc{Metis} is not automatically found, setting the `METIS_INCLUDE_DIR` and `METIS_LIBRARY` +If \metis is not automatically found, setting the `METIS_INCLUDE_DIR` and `METIS_LIBRARY` cmake variables is necessary. | Variable | Description | Type | | :- | :- | :- | -| `METIS_INCLUDE_DIR` | Directory of \sc{Metis} default installation | CMAKE | +| `METIS_INCLUDE_DIR` | Directory of \metis default installation | CMAKE | | `METIS_LIBRARY` | Directory containing the `libmetis.so or .lib` file | CMAKE | \subsection installation_tbb TBB Library -If \sc{Tbb} is not automatically found, the user must set the `TBB_ROOT` +If \tbb is not automatically found, the user must set the `TBB_ROOT` environment variable. The environment variable `TBB_ARCH_PLATFORM=/` must be set. `` is `ia32` or `intel64`. `` describes the Linux kernel, gcc version or Visual Studio version used. It should be set to what is used in `$TBB_ROOT/lib/`. @@ -328,7 +328,7 @@ Note that the variables in the table below are being used. | Variable | Description | Type | | :- | :- | :- | -| `TBB_ROOT` | Directory of \sc{Tbb} default installation | Environment | +| `TBB_ROOT` | Directory of \tbb default installation | Environment | | `TBB_INCLUDE_DIRS` | Directory containing the `tbb/tbb.h` file | CMake | | `TBB_LIBRARY_DIRS` | Directory(ies) containing the compiled TBB libraries | CMake | | `TBB_LIBRARIES` | Full pathnames of the compiled TBB libraries (both release and debug versions, using "optimized" and "debug" CMake keywords). Note that if the debug versions are not found, the release versions will be used instead for the debug mode. | CMake | diff --git a/Documentation/doc/Documentation/advanced/Installation.txt b/Documentation/doc/Documentation/advanced/Installation.txt index 314ead765e1..e5dd13a0e80 100644 --- a/Documentation/doc/Documentation/advanced/Installation.txt +++ b/Documentation/doc/Documentation/advanced/Installation.txt @@ -60,10 +60,10 @@ Note that some libraries have specific dependencies in addition to the essential | Library | CMake Variable | Functionality | Dependencies | | :-------- | :------------- | :------------ | :----------- | -| `%CGAL` | none | Main library | \sc{Gmp}, \sc{Mpfr}, \sc{Boost} (headers) | -| `CGAL_Core` | `WITH_CGAL_Core` | The %CORE library for algebraic numbers.\cgalFootnote{CGAL_Core is not part of \cgal, but a custom version of the \sc{Core} library distributed by \cgal for the user convenience and it has it's own license.} | \sc{Gmp} and \sc{Mpfr} | -| `CGAL_ImageIO` | `WITH_CGAL_ImageIO` | Utilities to read and write image files | \sc{zlib}, \sc{Vtk} (optional) | -| `CGAL_Qt5` | `WITH_CGAL_Qt5` | `QGraphicsView` support for \sc{Qt}5-based demos | \sc{Qt}5 | +| `%CGAL` | none | Main library | \gmp, \mpfr, \boost (headers) | +| `CGAL_Core` | `WITH_CGAL_Core` | The %CORE library for algebraic numbers.\cgalFootnote{CGAL_Core is not part of \cgal, but a custom version of the \core library distributed by \cgal for the user convenience and it has it's own license.} | \gmp and \mpfr | +| `CGAL_ImageIO` | `WITH_CGAL_ImageIO` | Utilities to read and write image files | \zlib, \vtk (optional) | +| `CGAL_Qt5` | `WITH_CGAL_Qt5` | `QGraphicsView` support for \qt5-based demos | \qt5 | Shared libraries, also called dynamic-link libraries, are built by default (`.so` on Linux, `.dylib` on macOS). You @@ -77,7 +77,7 @@ the \cgal libraries, unless you set the variables `WITH_examples=ON` and/or `WIT Additionally, even when configured with \cgal, they are not automatically built along with the libraries. You must build the `examples` or `demos` targets (or IDE projects) explicitly. -If you do not plan to compile any demos, you may skip some of the dependencies (such as \sc{Qt}), +If you do not plan to compile any demos, you may skip some of the dependencies (such as \qt), as the corresponding \cgal-libraries will not be used. Note, however, that your own demos might need these \cgal-libraries and thus their dependencies. See the page \ref secessential3rdpartysoftware for more information. @@ -215,7 +215,7 @@ The nature of the build files depends on the generator used during configuration contain several targets, one per library, and a default global target corresponding to all the libraries. -For example, in a \sc{Unix}-like environment the default generator produces makefiles. +For example, in a \unix-like environment the default generator produces makefiles. You can use the `make` command-line tool for the succeeding build step as follows: # build all the selected libraries at once @@ -277,7 +277,7 @@ the installation simply amounts to: \cgalAdvancedBegin The files are copied into a directory tree relative to the installation directory determined by the -CMake variable `CMAKE_INSTALL_PREFIX`. This variable defaults to `/usr/local` under \sc{Unix}-like operating systems. +CMake variable `CMAKE_INSTALL_PREFIX`. This variable defaults to `/usr/local` under \unix-like operating systems. If you want to install to a different location, you must override that CMake variable explicitly at the configuration time and not when executing the install step. \cgalAdvancedEnd diff --git a/Documentation/doc/Documentation/manual.txt b/Documentation/doc/Documentation/manual.txt index 38bc7bb37ee..060c0686bd4 100644 --- a/Documentation/doc/Documentation/manual.txt +++ b/Documentation/doc/Documentation/manual.txt @@ -11,7 +11,7 @@ of computational geometry. Each part consists of several chapters, and each chapter is split into a *User Manual* and a *Reference Manual*. The User Manual gives the general idea and comes with examples. -The Reference Manual presents the \sc{Api} of the various classes +The Reference Manual presents the \api of the various classes and functions. The manual has a \ref packages with a short paragraph explaining diff --git a/Documentation/doc/Documentation/windows.txt b/Documentation/doc/Documentation/windows.txt index 77021a27a28..3765cf34e58 100644 --- a/Documentation/doc/Documentation/windows.txt +++ b/Documentation/doc/Documentation/windows.txt @@ -2,8 +2,8 @@ \page windows Using %CGAL on Windows (with Visual C++) \cgalAutoToc -\cgal \cgalReleaseNumber is supported for the following \sc{MS} Visual `C++` compilers: -14.0, 15.9, 16.0 (\sc{Visual Studio} 2015, 2017, and 2019). +\cgal \cgalReleaseNumber is supported for the following \ms Visual `C++` compilers: +14.0, 15.9, 16.0 (\visualstudio 2015, 2017, and 2019). \cgal is a library that has mandatory dependencies that must be first installed: \ref thirdpartyBoost and \ref thirdpartyMPFR. @@ -16,9 +16,9 @@ installation instructions. If you choose to use `vcpkg`, you might have to bootstrap and download and compile it, but from then on `vcpkg` will make your life easier. -On the other hand, if you need to specify a specific version, or have already installed +On the other hand, if you need to use a specific version, or have already installed a certain version of a dependency and do not wish to potentially have multiple versions installed, -you will want to use the \cgal Installer. +you will want to use the \cgal source archive. We explain the two approaches in the next two sections. @@ -43,12 +43,16 @@ We refer to the official documentation of `vcpkg` if you want to compile for an older version of a compiler. +Because of a bug with gmp in vcpkg for windows, you need to install `yasm-tool` in 32 bits to be able to correctly build gmp 64bits, needed for cgal: + + C:\dev\vcpkg> ./vcpkg.exe install yasm-tool:x86-windows + You are now ready to install \cgal: C:\dev\vcpkg> ./vcpkg.exe install cgal -This will take several minutes as it downloads \mpir (a fork of \gmp), -\mpfr, all boost header files, and it will compile \mpir and \mpfr, as well +This will take several minutes as it downloads \gmp, +\mpfr, all boost header files, and it will compile \gmp and \mpfr, as well as several boost libraries. Afterwards, you will find the include files, libraries, and dlls in the subdirectory `C:\dev\vcpkg\installed\x64-windows`. @@ -146,11 +150,19 @@ you are advised to look at the `CMakeLists.txt` files in the example folder of the package(s) that you are using to learn how to specify \cgal and additional third party dependencies. -\section install-with-installer Installing with the CGAL Installer +\section install-from-source Installing from the Source Archive + +You can download and extract `CGAL-\cgalReleaseNumber``.zip` from https://www.cgal.org/download/windows.html. + +\subsection ssect-installer-gmp-mpfr Installing GMP and MPFR + +Precompiled version of \gmp and \mpfr are provided in the asset GMP and MPFR libraries, for Windows 64bits +from https://github.com/CGAL/cgal/releases. +If you only install those libraries to use \cgal, then you should extract this archive inside the directory +`CGAL-\cgalReleaseNumber` created when extracting the \cgal zip source archive. +That way those dependencies will be automatically detected by cmake +(you should then get the directory `CGAL-\cgalReleaseNumber``\``auxiliary``\``gmp`). -You can download and run `CGAL-\cgalReleaseNumber``-Setup.exe` from https://www.cgal.org/download/windows.html. -It is a self-extracting executable that downloads the \cgal header files, and optionally the source code of the -examples and demos. Additionally, it can download precompiled versions of \gmp and \mpfr. \subsection ssect-installer-boost Installing Boost @@ -267,9 +279,4 @@ you are advised to look at the `CMakeLists.txt` files in the example folder of the package(s) that you are using to learn how to specify \cgal and additional third party dependencies. -\section install-with-tarball Installing from the Source Archive - -Instead of the installer you can also download release tarballs. The sole difference -is that the installer also downloads precompiled \gmp and \mpfr libraries. - */ diff --git a/Documentation/doc/biblio/cgal_manual.bib b/Documentation/doc/biblio/cgal_manual.bib index 35b6b8ba4f1..f63166e26f9 100644 --- a/Documentation/doc/biblio/cgal_manual.bib +++ b/Documentation/doc/biblio/cgal_manual.bib @@ -659,6 +659,25 @@ Mourrain and Monique Teillaud" keywords = "Convex hull problem, Frame, Linear programming, Data envelopment analysis, Redundancy" } +@article{cgal:dl-cginc-19, + author = {Despr\'{e}, Vincent and Lazarus, Francis}, + title = {Computing the Geometric Intersection Number of Curves}, + year = {2019}, + issue_date = {December 2019}, + publisher = {Association for Computing Machinery}, + address = {New York, NY, USA}, + volume = {66}, + number = {6}, + issn = {0004-5411}, + url = {https://doi.org/10.1145/3363367}, + doi = {10.1145/3363367}, + journal = {J. ACM}, + month = nov, + articleno = {45}, + numpages = {49}, + keywords = {combinatorial geodesic, Computational topology, intersection number, curves on surfaces} +} + @unpublished{cgal:dl-cosfa-08, author = "J.H. Dul\'a and F.J. L\'opez", title = "Competing Output-Sensitive Frame Algorithms", diff --git a/Documentation/doc/resources/1.8.13/BaseDoxyfile.in b/Documentation/doc/resources/1.8.13/BaseDoxyfile.in index 85d7742a660..93ef2198d79 100644 --- a/Documentation/doc/resources/1.8.13/BaseDoxyfile.in +++ b/Documentation/doc/resources/1.8.13/BaseDoxyfile.in @@ -228,19 +228,53 @@ TAB_SIZE = 4 # "Side Effects:". You can put \n's in the value part of an alias to insert # newlines. -ALIASES = "sc{1}=\1" \ - "cgal=\sc{%CGAL}" \ - "protocgal=\sc{C++gal}" \ - "plageo=\sc{Plageo}" \ - "stl=\sc{STL}" \ - "gmp=\sc{GMP}" \ - "mpir=\sc{MPIR}" \ - "mpfr=\sc{MPFR}" \ - "leda=\sc{LEDA}" \ - "gcc=\sc{GCC}" \ - "cpp=\sc{C++}" \ - "cpp11=\sc{C++11}" \ - "CC=\sc{C++}" \ +ALIASES = "cgal=CGAL" \ + "protocgal=C++gal" \ + "plageo=Plageo" \ + "stl=STL" \ + "gmp=GMP" \ + "gmpxx=GMPXX" \ + "mpir=MPIR" \ + "mpfr=MPFR" \ + "leda=LEDA" \ + "gcc=GCC" \ + "dcel=DCEL" \ + "bgl=BGL" \ + "boost=Boost" \ + "gnu=GNU" \ + "ms=MS" \ + "qt=Qt" \ + "qt5=Qt5" \ + "eigen=Eigen" \ + "opengr=OpenGR" \ + "libpointmatcher=libpointmatcher" \ + "core=Core" \ + "mpfi=MPFI" \ + "ntl=NTL" \ + "pdb=PDB" \ + "esbtl=ESBTL" \ + "tbb=TBB" \ + "laslib=LASlib" \ + "opencv=OpenCV" \ + "tensorflow=TensorFlow" \ + "metis=METIS" \ + "zlib=zlib" \ + "ceres=Ceres" \ + "glpk=GLPK" \ + "scip=SCIP" \ + "rs=RS" \ + "rs3=RS3" \ + "unix=Unix" \ + "api=API" \ + "vtk=VTK" \ + "visualstudio=Visual Studio" \ + "taucs=TAUCS" \ + "lapack=LAPACK" \ + "blas=BLAS" \ + "opennl=OpenNL" \ + "cpp=C++" \ + "cpp11=C++11" \ + "CC=C++" \ "cgalExample{1}=
    File \ref \1 \include \1" \ "cgalFigureAnchor{1}=\anchor fig__\1" \ "cgalFigureRef{1}=\ref fig__\1" \ @@ -950,7 +984,7 @@ EXCLUDE_SYMBOLS = Tr \ Fb \ K \ Traits \ - internal + internal # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include diff --git a/Documentation/doc/resources/1.8.14/BaseDoxyfile.in b/Documentation/doc/resources/1.8.14/BaseDoxyfile.in index aad98822d2f..faca6fc348e 100644 --- a/Documentation/doc/resources/1.8.14/BaseDoxyfile.in +++ b/Documentation/doc/resources/1.8.14/BaseDoxyfile.in @@ -229,19 +229,53 @@ TAB_SIZE = 4 # newlines (in the resulting output). You can put ^^ in the value part of an # alias to insert a newline as if a physical newline was in the original file. -ALIASES = "sc{1}=\1" \ - "cgal=\sc{%CGAL}" \ - "protocgal=\sc{C++gal}" \ - "plageo=\sc{Plageo}" \ - "stl=\sc{STL}" \ - "gmp=\sc{GMP}" \ - "mpir=\sc{MPIR}" \ - "mpfr=\sc{MPFR}" \ - "leda=\sc{LEDA}" \ - "gcc=\sc{GCC}" \ - "cpp=\sc{C++}" \ - "cpp11=\sc{C++11}" \ - "CC=\sc{C++}" \ +ALIASES = "cgal=CGAL" \ + "protocgal=C++gal" \ + "plageo=Plageo" \ + "stl=STL" \ + "gmp=GMP" \ + "gmpxx=GMPXX" \ + "mpir=MPIR" \ + "mpfr=MPFR" \ + "leda=LEDA" \ + "gcc=GCC" \ + "dcel=DCEL" \ + "bgl=BGL" \ + "boost=Boost" \ + "gnu=GNU" \ + "ms=MS" \ + "qt=Qt" \ + "qt5=Qt5" \ + "eigen=Eigen" \ + "opengr=OpenGR" \ + "libpointmatcher=libpointmatcher" \ + "core=Core" \ + "mpfi=MPFI" \ + "ntl=NTL" \ + "pdb=PDB" \ + "esbtl=ESBTL" \ + "tbb=TBB" \ + "laslib=LASlib" \ + "opencv=OpenCV" \ + "tensorflow=TensorFlow" \ + "metis=METIS" \ + "zlib=zlib" \ + "ceres=Ceres" \ + "glpk=GLPK" \ + "scip=SCIP" \ + "rs=RS" \ + "rs3=RS3" \ + "unix=Unix" \ + "api=API" \ + "vtk=VTK" \ + "visualstudio=Visual Studio" \ + "taucs=TAUCS" \ + "lapack=LAPACK" \ + "blas=BLAS" \ + "opennl=OpenNL" \ + "cpp=C++" \ + "cpp11=C++11" \ + "CC=C++" \ "cgalExample{1}=
    File \ref \1 \include \1" \ "cgalFigureAnchor{1}=\anchor fig__\1" \ "cgalFigureRef{1}=\ref fig__\1" \ @@ -941,7 +975,7 @@ EXCLUDE_SYMBOLS = Tr \ Fb \ K \ Traits \ - internal + internal # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include diff --git a/Documentation/doc/resources/1.8.20/BaseDoxyfile.in b/Documentation/doc/resources/1.8.20/BaseDoxyfile.in index e7cce2eb165..767fa9f07b2 100644 --- a/Documentation/doc/resources/1.8.20/BaseDoxyfile.in +++ b/Documentation/doc/resources/1.8.20/BaseDoxyfile.in @@ -93,14 +93,6 @@ ALLOW_UNICODE_NAMES = NO OUTPUT_LANGUAGE = English -# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all generated output in the proper direction. -# Possible values are: None, LTR, RTL and Context. -# The default value is: None. - -OUTPUT_TEXT_DIRECTION = None - # If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. @@ -259,19 +251,53 @@ TAB_SIZE = 4 # commands \{ and \} for these it is advised to use the version @{ and @} or use # a double escape (\\{ and \\}) -ALIASES = "sc{1}=\1" \ - "cgal=\sc{%CGAL}" \ - "protocgal=\sc{C++gal}" \ - "plageo=\sc{Plageo}" \ - "stl=\sc{STL}" \ - "gmp=\sc{GMP}" \ - "mpir=\sc{MPIR}" \ - "mpfr=\sc{MPFR}" \ - "leda=\sc{LEDA}" \ - "gcc=\sc{GCC}" \ - "cpp=\sc{C++}" \ - "cpp11=\sc{C++11}" \ - "CC=\sc{C++}" \ +ALIASES = "cgal=CGAL" \ + "protocgal=C++gal" \ + "plageo=Plageo" \ + "stl=STL" \ + "gmp=GMP" \ + "gmpxx=GMPXX" \ + "mpir=MPIR" \ + "mpfr=MPFR" \ + "leda=LEDA" \ + "gcc=GCC" \ + "dcel=DCEL" \ + "bgl=BGL" \ + "boost=Boost" \ + "gnu=GNU" \ + "ms=MS" \ + "qt=Qt" \ + "qt5=Qt5" \ + "eigen=Eigen" \ + "opengr=OpenGR" \ + "libpointmatcher=libpointmatcher" \ + "core=Core" \ + "mpfi=MPFI" \ + "ntl=NTL" \ + "pdb=PDB" \ + "esbtl=ESBTL" \ + "tbb=TBB" \ + "laslib=LASlib" \ + "opencv=OpenCV" \ + "tensorflow=TensorFlow" \ + "metis=METIS" \ + "zlib=zlib" \ + "ceres=Ceres" \ + "glpk=GLPK" \ + "scip=SCIP" \ + "rs=RS" \ + "rs3=RS3" \ + "unix=Unix" \ + "api=API" \ + "vtk=VTK" \ + "visualstudio=Visual Studio" \ + "taucs=TAUCS" \ + "lapack=LAPACK" \ + "blas=BLAS" \ + "opennl=OpenNL" \ + "cpp=C++" \ + "cpp11=C++11" \ + "CC=C++" \ "cgalExample{1}=
    File \ref \1 \include \1" \ "cgalFigureAnchor{1}=\anchor fig__\1" \ "cgalFigureRef{1}=\ref fig__\1" \ @@ -1006,7 +1032,7 @@ EXCLUDE_SYMBOLS = Tr \ Fb \ K \ Traits \ - internal + internal # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include diff --git a/Documentation/doc/resources/1.8.4/BaseDoxyfile.in b/Documentation/doc/resources/1.8.4/BaseDoxyfile.in index d5b6d350ea7..eaca76a8e42 100644 --- a/Documentation/doc/resources/1.8.4/BaseDoxyfile.in +++ b/Documentation/doc/resources/1.8.4/BaseDoxyfile.in @@ -197,19 +197,54 @@ TAB_SIZE = 4 # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. -ALIASES = "sc{1}=\1" -ALIASES += "cgal=\sc{%CGAL}" -ALIASES += "protocgal=\sc{C++gal}" -ALIASES += "plageo=\sc{Plageo}" -ALIASES += "gmp=\sc{GMP}" -ALIASES += "mpir=\sc{MPIR}" -ALIASES += "mpfr=\sc{MPFR}" -ALIASES += "stl=\sc{STL}" -ALIASES += "leda=\sc{LEDA}" -ALIASES += "gcc=\sc{GCC}" -ALIASES += "cpp=\sc{C++}" -ALIASES += "cpp11=\sc{C++11}" -ALIASES += "CC=\sc{C++}" +ALIASES = "cgal=CGAL" +ALIASES += "protocgal=C++gal" +ALIASES += "plageo=Plageo" +ALIASES += "stl=STL" +ALIASES += "gmp=GMP" +ALIASES += "gmpxx=GMPXX" +ALIASES += "mpir=MPIR" +ALIASES += "mpfr=MPFR" +ALIASES += "leda=LEDA" +ALIASES += "gcc=GCC" +ALIASES += "dcel=DCEL" +ALIASES += "bgl=BGL" +ALIASES += "boost=Boost" +ALIASES += "gnu=GNU" +ALIASES += "ms=MS" +ALIASES += "qt=Qt" +ALIASES += "qt5=Qt5" +ALIASES += "eigen=Eigen" +ALIASES += "opengr=OpenGR" +ALIASES += "libpointmatcher=libpointmatcher" +ALIASES += "core=Core" +ALIASES += "mpfi=MPFI" +ALIASES += "ntl=NTL" +ALIASES += "pdb=PDB" +ALIASES += "esbtl=ESBTL" +ALIASES += "tbb=TBB" +ALIASES += "laslib=LASlib" +ALIASES += "opencv=OpenCV" +ALIASES += "tensorflow=TensorFlow" +ALIASES += "metis=METIS" +ALIASES += "zlib=zlib" +ALIASES += "ceres=Ceres" +ALIASES += "glpk=GLPK" +ALIASES += "scip=SCIP" +ALIASES += "rs=RS" +ALIASES += "rs3=RS3" +ALIASES += "unix=Unix" +ALIASES += "api=API" +ALIASES += "vtk=VTK" +ALIASES += "visualstudio=Visual Studio" +ALIASES += "taucs=TAUCS" +ALIASES += "lapack=LAPACK" +ALIASES += "blas=BLAS" +ALIASES += "opennl=OpenNL" +ALIASES += "cpp=C++" +ALIASES += "cpp11=C++11" +ALIASES += "CC=C++" + ALIASES += "cgalExample{1}=
    File \ref \1 \include \1" ALIASES += "cgalFigureAnchor{1}=\anchor fig__\1" ALIASES += "cgalFigureRef{1}=\ref fig__\1" diff --git a/Documentation/doc/scripts/generate_how_to_cite.py b/Documentation/doc/scripts/generate_how_to_cite.py index caad53d6392..2120824773e 100644 --- a/Documentation/doc/scripts/generate_how_to_cite.py +++ b/Documentation/doc/scripts/generate_how_to_cite.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python # coding: utf8 import re diff --git a/Documentation/doc/scripts/html_output_post_processing.py b/Documentation/doc/scripts/html_output_post_processing.py index f07bd3d2ced..4771a010ae5 100755 --- a/Documentation/doc/scripts/html_output_post_processing.py +++ b/Documentation/doc/scripts/html_output_post_processing.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python # Copyright (c) 2012 GeometryFactory (France). All rights reserved. # All rights reserved. # diff --git a/Documentation/doc/scripts/pkglist_filter.py b/Documentation/doc/scripts/pkglist_filter.py index af99777d529..92208a6f4d9 100755 --- a/Documentation/doc/scripts/pkglist_filter.py +++ b/Documentation/doc/scripts/pkglist_filter.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python import codecs import re diff --git a/Documentation/doc/scripts/testsuite.py b/Documentation/doc/scripts/testsuite.py index 1fda305b1e0..255191e61c4 100755 --- a/Documentation/doc/scripts/testsuite.py +++ b/Documentation/doc/scripts/testsuite.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python # Copyright (c) 2012 GeometryFactory (France). All rights reserved. # All rights reserved. # diff --git a/Envelope_3/doc/Envelope_3/Envelope_3.txt b/Envelope_3/doc/Envelope_3/Envelope_3.txt index 570cd58c03d..f87ee9b9127 100644 --- a/Envelope_3/doc/Envelope_3/Envelope_3.txt +++ b/Envelope_3/doc/Envelope_3/Envelope_3.txt @@ -58,7 +58,7 @@ both these diagrams as envelope diagrams. It is easy to see that an envelope diagram is no more than a planar arrangement (see Chapter \ref chapterArrangement_on_surface_2 "2D Arrangements"), represented -using an extended \sc{Dcel} structure, such that every \sc{Dcel} +using an extended \dcel structure, such that every \dcel record (namely each face, halfedge and vertex) stores an additional container of it originators: the \f$ xy\f$-monotone surfaces that induce this feature. diff --git a/Filtered_kernel/include/CGAL/Filtered_predicate.h b/Filtered_kernel/include/CGAL/Filtered_predicate.h index 63199a63a32..da9e4b1c4fb 100644 --- a/Filtered_kernel/include/CGAL/Filtered_predicate.h +++ b/Filtered_kernel/include/CGAL/Filtered_predicate.h @@ -37,6 +37,10 @@ namespace CGAL { // not, or we let all this up to the compiler optimizer to figure out ? // - Some caching could be done at the Point_2 level. +// Protection is undocumented and currently always true, meaning that it +// assumes a default rounding mode of round-to-nearest. false would correspond +// to a default of round-towards-infinity, so interval arithmetic does not +// require protection but regular code may. template class Filtered_predicate diff --git a/Filtered_kernel/include/CGAL/Lazy.h b/Filtered_kernel/include/CGAL/Lazy.h index 539ebbff948..82d6ff20f58 100644 --- a/Filtered_kernel/include/CGAL/Lazy.h +++ b/Filtered_kernel/include/CGAL/Lazy.h @@ -874,7 +874,7 @@ struct Lazy_construction_bbox template -struct Lazy_construction_optional +struct Lazy_construction_optional_for_polygonal_envelope { static const bool Protection = true; typedef typename LK::Approximate_kernel AK; diff --git a/Filtered_kernel/include/CGAL/Lazy_kernel.h b/Filtered_kernel/include/CGAL/Lazy_kernel.h index 71edc17eff7..89a84b5f150 100644 --- a/Filtered_kernel/include/CGAL/Lazy_kernel.h +++ b/Filtered_kernel/include/CGAL/Lazy_kernel.h @@ -178,7 +178,7 @@ private: // The case distinction goes as follows: // result_type == FT => NT // result_type == Object => Object - // result_type == boost::optional => OPTIONAL_ + // result_type == boost::optional => OPTIONAL_ Only for Intersect_point_3_for_polyhedral_envelope which returns a handle for a singleton // result_type == Bbox_2 || result_type == Bbox_3 => BBOX // default => NONE // no result_type => NONE @@ -214,7 +214,7 @@ private: CGAL_WRAPPER_TRAIT(Intersect_2, VARIANT) CGAL_WRAPPER_TRAIT(Intersect_3, VARIANT) - CGAL_WRAPPER_TRAIT(Intersect_point_3, OPTIONAL_) + CGAL_WRAPPER_TRAIT(Intersect_point_3_for_polyhedral_envelope, OPTIONAL_) CGAL_WRAPPER_TRAIT(Compute_squared_radius_2, NT) CGAL_WRAPPER_TRAIT(Compute_x_3, NT) CGAL_WRAPPER_TRAIT(Compute_y_3, NT) @@ -258,7 +258,7 @@ private: template struct Select_wrapper_impl { template - struct apply { typedef Lazy_construction_optional type; }; + struct apply { typedef Lazy_construction_optional_for_polygonal_envelope type; }; }; template diff --git a/GraphicsView/demo/L1_Voronoi_diagram_2/include/CGAL/L1_voronoi_traits_2.h b/GraphicsView/demo/L1_Voronoi_diagram_2/include/CGAL/L1_voronoi_traits_2.h index 91adae16d13..7b23ba84ef7 100644 --- a/GraphicsView/demo/L1_Voronoi_diagram_2/include/CGAL/L1_voronoi_traits_2.h +++ b/GraphicsView/demo/L1_Voronoi_diagram_2/include/CGAL/L1_voronoi_traits_2.h @@ -88,7 +88,7 @@ public: // Walk on the horizontal edge of the rectangle and then on the vertical. - // There is a chance that the width of the rectangle is smaller then the mid-dist. + // There is a chance that the width of the rectangle is smaller than the mid-dist. FT walk_x = (CGAL::min)(abs_x, dist); mid_x += sign_x * walk_x; dist -= walk_x; diff --git a/GraphicsView/doc/GraphicsView/PackageDescription.txt b/GraphicsView/doc/GraphicsView/PackageDescription.txt index a6597c649e5..3c32ad7863c 100644 --- a/GraphicsView/doc/GraphicsView/PackageDescription.txt +++ b/GraphicsView/doc/GraphicsView/PackageDescription.txt @@ -18,7 +18,7 @@ \cgalPkgSummaryEnd \cgalPkgShortInfoBegin \cgalPkgSince{3.4} -\cgalPkgDependsOn{\sc{Qt} 5} +\cgalPkgDependsOn{\qt 5} \cgalPkgBib{cgal:fr-cqgvf} \cgalPkgLicense{\ref licensesGPL "GPL"} \cgalPkgShortInfoEnd diff --git a/GraphicsView/include/CGAL/Basic_shaders.h b/GraphicsView/include/CGAL/Basic_shaders.h new file mode 100644 index 00000000000..1e9f7697c0a --- /dev/null +++ b/GraphicsView/include/CGAL/Basic_shaders.h @@ -0,0 +1,285 @@ +// Copyright (c) 2018 GeometryFactory Sarl (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Guillaume Damiand + +#ifndef CGAL_BASIC_SHADERS_H +#define CGAL_BASIC_SHADERS_H + +#include + +namespace CGAL +{ + +//------------------------------------------------------------------------------ +const char vertex_source_color[]=R"DELIM( +#version 150 +in highp vec4 vertex; +in highp vec3 normal; +in highp vec3 color; + +uniform highp mat4 mvp_matrix; +uniform highp mat4 mv_matrix; +uniform highp float point_size; + +out highp vec4 fP; +out highp vec3 fN; +out highp vec4 fColor; +out highp vec4 m_vertex; + +void main(void) +{ + fP = mv_matrix * vertex; + fN = mat3(mv_matrix)* normal; + fColor = vec4(color, 1.0); + gl_PointSize = point_size; + + m_vertex = vertex; + + gl_Position = mvp_matrix * vertex; +} +)DELIM"; + +const char fragment_source_color[]=R"DELIM( +#version 150 +in highp vec4 fP; +in highp vec3 fN; +in highp vec4 fColor; +in highp vec4 m_vertex; + +uniform highp vec4 light_pos; +uniform highp vec4 light_diff; +uniform highp vec4 light_spec; +uniform highp vec4 light_amb; +uniform highp float spec_power; + +uniform highp vec4 clipPlane; +uniform highp vec4 pointPlane; +uniform highp float rendering_mode; +uniform highp float rendering_transparency; + +out highp vec4 out_color; + +void main(void) +{ + highp vec3 L = light_pos.xyz - fP.xyz; + highp vec3 V = -fP.xyz; + + highp vec3 N = normalize(fN); + L = normalize(L); + V = normalize(V); + + highp vec3 R = reflect(-L, N); + highp vec4 diffuse = vec4(max(dot(N,L), 0.0) * light_diff.rgb * fColor.rgb, 1.0); + highp vec4 ambient = vec4(light_amb.rgb * fColor.rgb, 1.0); + highp vec4 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; + + // onPlane == 1: inside clipping plane, should be solid; + // onPlane == -1: outside clipping plane, should be transparent; + // onPlane == 0: on clipping plane, whatever; + float onPlane = sign(dot((m_vertex.xyz-pointPlane.xyz), clipPlane.xyz)); + + // rendering_mode == -1: draw all solid; + // rendering_mode == 0: draw solid only; + // rendering_mode == 1: draw transparent only; + if (rendering_mode == (onPlane+1)/2) { + // discard other than the corresponding half when rendering + discard; + } + + // draw corresponding part + out_color = rendering_mode < 1 ? (diffuse + ambient) : + vec4(diffuse.rgb + ambient.rgb, rendering_transparency); +} +)DELIM"; + +const char vertex_source_p_l[]=R"DELIM( +#version 150 +in highp vec4 vertex; +in highp vec3 color; + +uniform highp mat4 mvp_matrix; +uniform highp float point_size; + +out highp vec4 fColor; +out highp vec4 m_vertex; + +void main(void) +{ + gl_PointSize = point_size; + fColor = vec4(color, 1.0); + m_vertex = vertex; + gl_Position = mvp_matrix * vertex; +} +)DELIM"; + +const char fragment_source_p_l[]=R"DELIM( +#version 150 +in highp vec4 fColor; +in highp vec4 m_vertex; + +uniform highp vec4 clipPlane; +uniform highp vec4 pointPlane; +uniform highp float rendering_mode; + +out highp vec4 out_color; + +void main(void) +{ + // onPlane == 1: inside clipping plane, should be solid; + // onPlane == -1: outside clipping plane, should be transparent; + // onPlane == 0: on clipping plane, whatever; + float onPlane = sign(dot((m_vertex.xyz-pointPlane.xyz), clipPlane.xyz)); + + // rendering_mode == -1: draw both inside and outside; + // rendering_mode == 0: draw inside only; + // rendering_mode == 1: draw outside only; + if (rendering_mode == (onPlane+1)/2) { + // discard other than the corresponding half when rendering + discard; + } + + out_color = fColor; +} +)DELIM"; + +const char vertex_source_clipping_plane[]=R"DELIM( +#version 150 +in highp vec4 vertex; + +uniform highp mat4 vp_matrix; +uniform highp mat4 m_matrix; + +void main(void) +{ + gl_Position = vp_matrix * m_matrix * vertex; +} +)DELIM"; + +const char fragment_source_clipping_plane[]=R"DELIM( +#version 150 +out highp vec4 out_color; +void main(void) +{ + out_color = vec4(0.0, 0.0, 0.0, 1.0); +} +)DELIM"; + +//------------------------------------------------------------------------------ +// compatibility shaders + +const char vertex_source_color_comp[]=R"DELIM( +in highp vec4 vertex; +in highp vec3 normal; +in highp vec3 color; + +uniform highp mat4 mvp_matrix; +uniform highp mat4 mv_matrix; +uniform highp float point_size; + +out highp vec4 fP; +out highp vec3 fN; +out highp vec4 fColor; + +void main(void) +{ + fP = mv_matrix * vertex; + highp mat3 mv_matrix_3; + mv_matrix_3[0] = mv_matrix[0].xyz; + mv_matrix_3[1] = mv_matrix[1].xyz; + mv_matrix_3[2] = mv_matrix[2].xyz; + fN = mv_matrix_3* normal; + fColor = vec4(color, 1.0); + gl_PointSize = point_size; + + gl_Position = mvp_matrix * vertex; +} +)DELIM"; + +const char fragment_source_color_comp[]=R"DELIM( +in highp vec4 fP; +in highp vec3 fN; +in highp vec4 fColor; + +uniform highp vec4 light_pos; +uniform highp vec4 light_diff; +uniform highp vec4 light_spec; +uniform highp vec4 light_amb; +uniform highp float spec_power ; + +out highp vec4 out_color; + +void main(void) +{ + highp vec3 L = light_pos.xyz - fP.xyz; + highp vec3 V = -fP.xyz; + + highp vec3 N = normalize(fN); + L = normalize(L); + V = normalize(V); + + highp vec3 R = reflect(-L, N); + highp vec4 diffuse = max(dot(N,L), 0.0) * light_diff * fColor; + highp vec4 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; + + out_color = light_amb*fColor + diffuse; +} +)DELIM"; + +const char vertex_source_p_l_comp[]=R"DELIM( +in highp vec4 vertex; +in highp vec3 color; + +uniform highp mat4 mvp_matrix; +uniform highp float point_size; + +out highp vec4 fColor; + +void main(void) +{ + gl_PointSize = point_size; + fColor = vec4(color, 1.0); + gl_Position = mvp_matrix * vertex; +} +)DELIM"; + +const char fragment_source_p_l_comp[]=R"DELIM( +in highp vec4 fColor; +out highp vec4 out_color; +void main(void) +{ + out_color = fColor; +} +)DELIM"; + +/* const char vertex_source_clipping_plane_comp[]=R"DELIM( +attribute highp vec4 vertex; + +uniform highp mat4 vp_matrix; +uniform highp mat4 m_matrix; + +void main(void) +{ + gl_Position = vp_matrix * m_matrix * vertex; +} +)DELIM"; + +const char fragment_source_clipping_plane_comp[]=R"DELIM( +out highp vec4 out_color; +void main(void) +{ + out_color = vec4(0.0, 0.0, 0.0, 1.0); +} +)DELIM"; +*/ + +} + +#endif // CGAL_BASIC_SHADERS_H diff --git a/GraphicsView/include/CGAL/Buffer_for_vao.h b/GraphicsView/include/CGAL/Buffer_for_vao.h index c27e24e50c9..2be331a35f5 100644 --- a/GraphicsView/include/CGAL/Buffer_for_vao.h +++ b/GraphicsView/include/CGAL/Buffer_for_vao.h @@ -908,7 +908,7 @@ protected: bool m_zero_y; /// True iff all points have y==0 bool m_zero_z; /// True iff all points have z==0 - bool m_inverse_normal;; + bool m_inverse_normal; // Local variables, used when we started a new face.g bool m_face_started; diff --git a/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h b/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h index 64538427139..f306e419ce7 100644 --- a/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h +++ b/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h @@ -31,8 +31,8 @@ #include #include +#include #include -#include #include #include #include @@ -48,180 +48,13 @@ #include #include +#include #include #include #include namespace CGAL { -//------------------------------------------------------------------------------ -const char vertex_source_color[] = - { - "#version 150 \n" - "in highp vec4 vertex;\n" - "in highp vec3 normal;\n" - "in highp vec3 color;\n" - - "uniform highp mat4 mvp_matrix;\n" - "uniform highp mat4 mv_matrix; \n" - - "out highp vec4 fP; \n" - "out highp vec3 fN; \n" - "out highp vec4 fColor; \n" - - "uniform highp float point_size; \n" - "void main(void)\n" - "{\n" - " fP = mv_matrix * vertex; \n" - " fN = mat3(mv_matrix)* normal; \n" - " fColor = vec4(color, 1.0); \n" - " gl_PointSize = point_size;\n" - " gl_Position = mvp_matrix * vertex;\n" - "}" - }; - -const char fragment_source_color[] = - { - "#version 150 \n" - "in highp vec4 fP; \n" - "in highp vec3 fN; \n" - "in highp vec4 fColor; \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 float spec_power ; \n" - "out vec4 out_color; \n" - - "void main(void) { \n" - " highp vec3 L = light_pos.xyz - fP.xyz; \n" - " highp vec3 V = -fP.xyz; \n" - - " highp vec3 N = normalize(fN); \n" - " L = normalize(L); \n" - " V = normalize(V); \n" - - " highp vec3 R = reflect(-L, N); \n" - " highp vec4 diffuse = max(dot(N,L), 0.0) * light_diff * fColor; \n" - " highp vec4 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; \n" - " out_color = light_amb*fColor + diffuse ; \n" - "} \n" - "\n" - }; - -const char vertex_source_p_l[] = - { - "#version 150 \n" - "in highp vec4 vertex;\n" - "in highp vec3 color;\n" - "uniform highp mat4 mvp_matrix;\n" - "out highp vec4 fColor; \n" - "uniform highp float point_size; \n" - "void main(void)\n" - "{\n" - " gl_PointSize = point_size;\n" - " fColor = vec4(color, 1.0); \n" - " gl_Position = mvp_matrix * vertex;\n" - "}" - }; - -const char fragment_source_p_l[] = - { - "#version 150 \n" - "in highp vec4 fColor; \n" - "out vec4 out_color; \n" - "void main(void) { \n" - "out_color = fColor; \n" - "} \n" - "\n" - }; - -//------------------------------------------------------------------------------ -// compatibility shaders - -const char vertex_source_color_comp[] = - { - "attribute highp vec4 vertex;\n" - "attribute highp vec3 normal;\n" - "attribute highp vec3 color;\n" - - "uniform highp mat4 mvp_matrix;\n" - "uniform highp mat4 mv_matrix; \n" - - "varying highp vec4 fP; \n" - "varying highp vec3 fN; \n" - "varying highp vec4 fColor; \n" - - "uniform highp float point_size; \n" - "void main(void)\n" - "{\n" - " fP = mv_matrix * vertex; \n" - " highp mat3 mv_matrix_3; \n" - " mv_matrix_3[0] = mv_matrix[0].xyz; \n" - " mv_matrix_3[1] = mv_matrix[1].xyz; \n" - " mv_matrix_3[2] = mv_matrix[2].xyz; \n" - " fN = mv_matrix_3* normal; \n" - " fColor = vec4(color, 1.0); \n" - " gl_PointSize = point_size;\n" - " gl_Position = mvp_matrix * vertex;\n" - "}" - }; - -const char fragment_source_color_comp[] = - { - "varying highp vec4 fP; \n" - "varying highp vec3 fN; \n" - "varying highp vec4 fColor; \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" - - " highp vec3 L = light_pos.xyz - fP.xyz; \n" - " highp vec3 V = -fP.xyz; \n" - - " highp vec3 N = normalize(fN); \n" - " L = normalize(L); \n" - " V = normalize(V); \n" - - " highp vec3 R = reflect(-L, N); \n" - " highp vec4 diffuse = max(dot(N,L), 0.0) * light_diff * fColor; \n" - " highp vec4 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; \n" - - "gl_FragColor = light_amb*fColor + diffuse ; \n" - "} \n" - "\n" - }; - -const char vertex_source_p_l_comp[] = - { - "attribute highp vec4 vertex;\n" - "attribute highp vec3 color;\n" - "uniform highp mat4 mvp_matrix;\n" - "varying highp vec4 fColor; \n" - "uniform highp float point_size; \n" - "void main(void)\n" - "{\n" - " gl_PointSize = point_size;\n" - " fColor = vec4(color, 1.0); \n" - " gl_Position = mvp_matrix * vertex;\n" - "}" - }; - -const char fragment_source_p_l_comp[] = - { - "varying highp vec4 fColor; \n" - "void main(void) { \n" - "gl_FragColor = fColor; \n" - "} \n" - "\n" - }; - - - //------------------------------------------------------------------------------ inline CGAL::Color get_random_color(CGAL::Random& random) { @@ -330,6 +163,8 @@ public: setShortcut(qglviewer::EXIT_VIEWER, ::Qt::CTRL+::Qt::Key_Q); // Add custom key description (see keyPressEvent). + setKeyDescription(::Qt::Key_C, "Switch clipping plane display mode"); + setKeyDescription(::Qt::Key_C+::Qt::AltModifier, "Toggle clipping plane rendering on/off"); setKeyDescription(::Qt::Key_E, "Toggles edges display"); setKeyDescription(::Qt::Key_M, "Toggles mono color"); setKeyDescription(::Qt::Key_N, "Inverse direction of normals"); @@ -346,6 +181,21 @@ public: setKeyDescription(::Qt::Key_PageUp, "Decrease light (all colors, use shift/alt/ctrl for one rgb component)"); setKeyDescription(::Qt::Key_O, "Toggles 2D mode only"); + // Add custom mouse description + setMouseBindingDescription(::Qt::Key_C, ::Qt::ControlModifier, ::Qt::LeftButton, "Rotate the clipping plane when enabled"); + setMouseBindingDescription(::Qt::Key_C, ::Qt::ControlModifier, ::Qt::RightButton, "Translate the clipping plane when enabled"); + setMouseBindingDescription(::Qt::Key_C, ::Qt::ControlModifier, ::Qt::MidButton, "Control the clipping plane transparency when enabled"); + + setMouseBinding(::Qt::ControlModifier, ::Qt::LeftButton, qglviewer::FRAME, qglviewer::NO_MOUSE_ACTION); + setMouseBinding(::Qt::ControlModifier, ::Qt::RightButton, qglviewer::FRAME, qglviewer::NO_MOUSE_ACTION); + setMouseBinding(::Qt::ControlModifier, ::Qt::MidButton, qglviewer::FRAME, qglviewer::NO_MOUSE_ACTION); + setWheelBinding(::Qt::ControlModifier, qglviewer::FRAME, qglviewer::NO_MOUSE_ACTION); + + setMouseBinding(::Qt::Key_C, ::Qt::ControlModifier, ::Qt::LeftButton, qglviewer::FRAME, qglviewer::ROTATE); + setMouseBinding(::Qt::Key_C, ::Qt::ControlModifier, ::Qt::RightButton, qglviewer::FRAME, qglviewer::TRANSLATE); + setMouseBinding(::Qt::Key_C, ::Qt::ControlModifier, ::Qt::MidButton, qglviewer::FRAME, qglviewer::ZOOM); + setWheelBinding(::Qt::Key_C, ::Qt::ControlModifier, qglviewer::FRAME, qglviewer::ZOOM); + if (title[0]==0) setWindowTitle("CGAL Basic Viewer"); else @@ -625,6 +475,7 @@ protected: { rendering_program_face.removeAllShaders(); rendering_program_p_l.removeAllShaders(); + rendering_program_clipping_plane.removeAllShaders(); // Create the buffers for (unsigned int i=0; icompileSourceCode(source_)) - { std::cerr<<"Compiling fragmentsource FAILED"<compileSourceCode(source_)) + { std::cerr << "Compiling vertex source for clipping plane FAILED" << std::endl; } + + source_ = fragment_source_clipping_plane; + + QOpenGLShader *fragment_shader_clipping_plane = new QOpenGLShader(QOpenGLShader::Fragment); + if (!fragment_shader_clipping_plane->compileSourceCode(source_)) + { std::cerr << "Compiling fragment source for clipping plane FAILED" << std::endl; } + + if (!rendering_program_clipping_plane.addShader(vertex_shader_clipping_plane)) + { std::cerr << "Adding vertex shader for clipping plane FAILED" << std::endl;} + if (!rendering_program_clipping_plane.addShader(fragment_shader_clipping_plane)) + { std::cerr << "Adding fragment shader for clipping plane FAILED" << std::endl; } + if (!rendering_program_clipping_plane.link()) + { std::cerr << "Linking Program for clipping plane FAILED" << std::endl; } + + } + + // source_ = isOpenGL_4_3() + // ? vertex_source_clipping_plane + // : vertex_source_clipping_plane_comp; + + // QOpenGLShader *vertex_shader_clipping_plane = new QOpenGLShader(QOpenGLShader::Vertex); + // if (!vertex_shader_clipping_plane->compileSourceCode(source_)) + // { std::cerr << "Compiling vertex source for clipping plane FAILED" << std::endl; } + + // source_ = isOpenGL_4_3() + // ? fragment_source_clipping_plane + // : fragment_source_clipping_plane_comp; + + // QOpenGLShader *fragment_shader_clipping_plane = new QOpenGLShader(QOpenGLShader::Fragment); + // if (!fragment_shader_clipping_plane->compileSourceCode(source_)) + // { std::cerr << "Compiling fragment source for clipping plane FAILED" << std::endl; } + + // if (!rendering_program_clipping_plane.addShader(vertex_shader_clipping_plane)) + // { std::cerr << "Adding vertex shader for clipping plane FAILED" << std::endl;} + // if (!rendering_program_clipping_plane.addShader(fragment_shader_clipping_plane)) + // { std::cerr << "Adding fragment shader for clipping plane FAILED" << std::endl; } + // if (!rendering_program_clipping_plane.link()) + // { std::cerr << "Linking Program for clipping plane FAILED" << std::endl; } } void initialize_buffers() @@ -964,6 +864,26 @@ protected: rendering_program_face.release(); + + // 6) clipping plane shader + if (isOpenGL_4_3()) + { + rendering_program_clipping_plane.bind(); + + vao[VAO_CLIPPING_PLANE].bind(); + ++bufn; + assert(bufn < NB_VBO_BUFFERS); + buffers[bufn].bind(); + buffers[bufn].allocate(arrays[POS_CLIPPING_PLANE].data(), + static_cast(arrays[POS_CLIPPING_PLANE].size() * sizeof(float))); + rendering_program_clipping_plane.enableAttributeArray("vertex"); + rendering_program_clipping_plane.setAttributeBuffer("vertex", GL_FLOAT, 0, 3); + + buffers[bufn].release(); + + rendering_program_clipping_plane.release(); + } + m_are_buffers_initialized = true; } @@ -1030,6 +950,25 @@ protected: int mvpLocation2 = rendering_program_p_l.uniformLocation("mvp_matrix"); rendering_program_p_l.setUniformValue(mvpLocation2, mvpMatrix); rendering_program_p_l.release(); + + + if (isOpenGL_4_3()) + { + QMatrix4x4 clipping_mMatrix; + clipping_mMatrix.setToIdentity(); + if(m_frame_plane) + { + for(int i=0; i< 16 ; i++) + clipping_mMatrix.data()[i] = m_frame_plane->matrix()[i]; + } + + rendering_program_clipping_plane.bind(); + int vpLocation = rendering_program_clipping_plane.uniformLocation("vp_matrix"); + int mLocation = rendering_program_clipping_plane.uniformLocation("m_matrix"); + rendering_program_clipping_plane.setUniformValue(vpLocation, mvpMatrix); + rendering_program_clipping_plane.setUniformValue(mLocation, clipping_mMatrix); + rendering_program_clipping_plane.release(); + } } // Returns true if the data structure lies on a plane @@ -1041,6 +980,16 @@ protected: virtual void draw() { glEnable(GL_DEPTH_TEST); + + QMatrix4x4 clipping_mMatrix; + clipping_mMatrix.setToIdentity(); + if(m_frame_plane) + { + for(int i=0; i< 16 ; i++) + clipping_mMatrix.data()[i] = m_frame_plane->matrix()[i]; + } + QVector4D clipPlane = clipping_mMatrix * QVector4D(0.0, 0.0, 1.0, 0.0); + QVector4D plane_point = clipping_mMatrix * QVector4D(0,0,0,1); if(!m_are_buffers_initialized) { initialize_buffers(); } @@ -1073,31 +1022,57 @@ protected: { rendering_program_p_l.bind(); - vao[VAO_MONO_POINTS].bind(); - color.setRgbF((double)m_vertices_mono_color.red()/(double)255, - (double)m_vertices_mono_color.green()/(double)255, - (double)m_vertices_mono_color.blue()/(double)255); - rendering_program_p_l.setAttributeValue("color",color); - rendering_program_p_l.setUniformValue("point_size", GLfloat(m_size_points)); - glDrawArrays(GL_POINTS, 0, static_cast(arrays[POS_MONO_POINTS].size()/3)); - vao[VAO_MONO_POINTS].release(); - - vao[VAO_COLORED_POINTS].bind(); - if (m_use_mono_color) - { + // rendering_mode == -1: draw all + // rendering_mode == 0: draw inside clipping plane + // rendering_mode == 1: draw outside clipping plane + auto renderer = [this, &color, &clipPlane, &plane_point](float rendering_mode) { + vao[VAO_MONO_POINTS].bind(); color.setRgbF((double)m_vertices_mono_color.red()/(double)255, (double)m_vertices_mono_color.green()/(double)255, - (double)m_vertices_mono_color.blue()/(double)255); - rendering_program_p_l.disableAttributeArray("color"); + (double)m_vertices_mono_color.blue()/(double)255); rendering_program_p_l.setAttributeValue("color",color); + rendering_program_p_l.setUniformValue("point_size", GLfloat(m_size_points)); + rendering_program_p_l.setUniformValue("clipPlane", clipPlane); + rendering_program_p_l.setUniformValue("pointPlane", plane_point); + rendering_program_p_l.setUniformValue("rendering_mode", rendering_mode); + glDrawArrays(GL_POINTS, 0, static_cast(arrays[POS_MONO_POINTS].size()/3)); + vao[VAO_MONO_POINTS].release(); + + vao[VAO_COLORED_POINTS].bind(); + if (m_use_mono_color) + { + color.setRgbF((double)m_vertices_mono_color.red()/(double)255, + (double)m_vertices_mono_color.green()/(double)255, + (double)m_vertices_mono_color.blue()/(double)255); + rendering_program_p_l.disableAttributeArray("color"); + rendering_program_p_l.setAttributeValue("color",color); + } + else + { + rendering_program_p_l.enableAttributeArray("color"); + } + rendering_program_p_l.setUniformValue("point_size", GLfloat(m_size_points)); + rendering_program_p_l.setUniformValue("clipPlane", clipPlane); + rendering_program_p_l.setUniformValue("pointPlane", plane_point); + rendering_program_p_l.setUniformValue("rendering_mode", rendering_mode); + glDrawArrays(GL_POINTS, 0, static_cast(arrays[POS_COLORED_POINTS].size()/3)); + vao[VAO_COLORED_POINTS].release(); + }; + + enum { + DRAW_ALL = -1, // draw all + DRAW_INSIDE_ONLY, // draw only the part inside the clipping plane + DRAW_OUTSIDE_ONLY // draw only the part outside the clipping plane + }; + + if (m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) + { + renderer(DRAW_INSIDE_ONLY); } else { - rendering_program_p_l.enableAttributeArray("color"); + renderer(DRAW_ALL); } - rendering_program_p_l.setUniformValue("point_size", GLfloat(m_size_points)); - glDrawArrays(GL_POINTS, 0, static_cast(arrays[POS_COLORED_POINTS].size()/3)); - vao[VAO_COLORED_POINTS].release(); rendering_program_p_l.release(); } @@ -1106,31 +1081,57 @@ protected: { rendering_program_p_l.bind(); - vao[VAO_MONO_SEGMENTS].bind(); - color.setRgbF((double)m_edges_mono_color.red()/(double)255, - (double)m_edges_mono_color.green()/(double)255, - (double)m_edges_mono_color.blue()/(double)255); - rendering_program_p_l.setAttributeValue("color",color); - glLineWidth(m_size_edges); - glDrawArrays(GL_LINES, 0, static_cast(arrays[POS_MONO_SEGMENTS].size()/3)); - vao[VAO_MONO_SEGMENTS].release(); - - vao[VAO_COLORED_SEGMENTS].bind(); - if (m_use_mono_color) - { + // rendering_mode == -1: draw all + // rendering_mode == 0: draw inside clipping plane + // rendering_mode == 1: draw outside clipping plane + auto renderer = [this, &color, &clipPlane, &plane_point](float rendering_mode) { + vao[VAO_MONO_SEGMENTS].bind(); color.setRgbF((double)m_edges_mono_color.red()/(double)255, (double)m_edges_mono_color.green()/(double)255, (double)m_edges_mono_color.blue()/(double)255); - rendering_program_p_l.disableAttributeArray("color"); rendering_program_p_l.setAttributeValue("color",color); + rendering_program_p_l.setUniformValue("clipPlane", clipPlane); + rendering_program_p_l.setUniformValue("pointPlane", plane_point); + rendering_program_p_l.setUniformValue("rendering_mode", rendering_mode); + glLineWidth(m_size_edges); + glDrawArrays(GL_LINES, 0, static_cast(arrays[POS_MONO_SEGMENTS].size()/3)); + vao[VAO_MONO_SEGMENTS].release(); + + vao[VAO_COLORED_SEGMENTS].bind(); + if (m_use_mono_color) + { + color.setRgbF((double)m_edges_mono_color.red()/(double)255, + (double)m_edges_mono_color.green()/(double)255, + (double)m_edges_mono_color.blue()/(double)255); + rendering_program_p_l.disableAttributeArray("color"); + rendering_program_p_l.setAttributeValue("color",color); + } + else + { + rendering_program_p_l.enableAttributeArray("color"); + } + rendering_program_p_l.setUniformValue("clipPlane", clipPlane); + rendering_program_p_l.setUniformValue("pointPlane", plane_point); + rendering_program_p_l.setUniformValue("rendering_mode", rendering_mode); + glLineWidth(m_size_edges); + glDrawArrays(GL_LINES, 0, static_cast(arrays[POS_COLORED_SEGMENTS].size()/3)); + vao[VAO_COLORED_SEGMENTS].release(); + }; + + enum { + DRAW_ALL = -1, // draw all + DRAW_INSIDE_ONLY, // draw only the part inside the clipping plane + DRAW_OUTSIDE_ONLY // draw only the part outside the clipping plane + }; + + if (m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) + { + renderer(DRAW_INSIDE_ONLY); } else { - rendering_program_p_l.enableAttributeArray("color"); + renderer(DRAW_ALL); } - glLineWidth(m_size_edges); - glDrawArrays(GL_LINES, 0, static_cast(arrays[POS_COLORED_SEGMENTS].size()/3)); - vao[VAO_COLORED_SEGMENTS].release(); rendering_program_p_l.release(); } @@ -1216,29 +1217,104 @@ protected: { rendering_program_face.bind(); + // reference: https://stackoverflow.com/questions/37780345/opengl-how-to-create-order-independent-transparency + // rendering_mode == -1: draw all as solid; + // rendering_mode == 0: draw solid only; + // rendering_mode == 1: draw transparent only; + auto renderer = [this, &color, &clipPlane, &plane_point](float rendering_mode) { + vao[VAO_MONO_FACES].bind(); color.setRgbF((double)m_faces_mono_color.red()/(double)255, (double)m_faces_mono_color.green()/(double)255, (double)m_faces_mono_color.blue()/(double)255); rendering_program_face.setAttributeValue("color",color); + rendering_program_face.setUniformValue("rendering_mode", rendering_mode); + rendering_program_face.setUniformValue("rendering_transparency", clipping_plane_rendering_transparency); + rendering_program_face.setUniformValue("clipPlane", clipPlane); + rendering_program_face.setUniformValue("pointPlane", plane_point); glDrawArrays(GL_TRIANGLES, 0, static_cast(arrays[POS_MONO_FACES].size()/3)); vao[VAO_MONO_FACES].release(); - vao[VAO_COLORED_FACES].bind(); - if (m_use_mono_color) + vao[VAO_COLORED_FACES].bind(); + if (m_use_mono_color) + { + color.setRgbF((double)m_faces_mono_color.red()/(double)255, + (double)m_faces_mono_color.green()/(double)255, + (double)m_faces_mono_color.blue()/(double)255); + rendering_program_face.disableAttributeArray("color"); + rendering_program_face.setAttributeValue("color",color); + } + else + { + rendering_program_face.enableAttributeArray("color"); + } + rendering_program_face.setUniformValue("rendering_mode", rendering_mode); + rendering_program_face.setUniformValue("rendering_transparency", clipping_plane_rendering_transparency); + rendering_program_face.setUniformValue("clipPlane", clipPlane); + rendering_program_face.setUniformValue("pointPlane", plane_point); + glDrawArrays(GL_TRIANGLES, 0, static_cast(arrays[POS_COLORED_FACES].size()/3)); + vao[VAO_COLORED_FACES].release(); + }; + + auto renderer_clipping_plane = [this](bool clipping_plane_rendering) { + if (!isOpenGL_4_3()) return; + if (!clipping_plane_rendering) return; + // render clipping plane here + rendering_program_clipping_plane.bind(); + vao[VAO_CLIPPING_PLANE].bind(); + glLineWidth(0.1f); + glDrawArrays(GL_LINES, 0, static_cast(arrays[POS_CLIPPING_PLANE].size() / 3)); + glLineWidth(1.0f); + vao[VAO_CLIPPING_PLANE].release(); + rendering_program_clipping_plane.release(); + }; + + enum { + DRAW_SOLID_ALL = -1, // draw all mesh in solid mode + DRAW_SOLID_HALF, // draw only the mesh inside the clipping plane as solid + DRAW_TRANSPARENT_HALF // draw only the mesh outside the clipping plane as transparent + }; + + if (m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_TRANSPARENT_HALF) { - color.setRgbF((double)m_faces_mono_color.red()/(double)255, - (double)m_faces_mono_color.green()/(double)255, - (double)m_faces_mono_color.blue()/(double)255); - rendering_program_face.disableAttributeArray("color"); - rendering_program_face.setAttributeValue("color",color); + // The z-buffer will prevent transparent objects from being displayed behind other transparent objects. + // Before rendering all transparent objects, disable z-testing first. + + // 1. draw solid first + renderer(DRAW_SOLID_HALF); + + // 2. draw transparent layer second with back face culling to avoid messy triangles + glDepthMask(false); //disable z-testing + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + glFrontFace(GL_CW); + renderer(DRAW_TRANSPARENT_HALF); + + // 3. draw solid again without culling and blend to make sure the solid mesh is visible + glDepthMask(true); //enable z-testing + glDisable(GL_CULL_FACE); + glDisable(GL_BLEND); + renderer(DRAW_SOLID_HALF); + + // 4. render clipping plane here + renderer_clipping_plane(clipping_plane_rendering); + } + else if (m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_WIRE_HALF || + m_use_clipping_plane == CLIPPING_PLANE_SOLID_HALF_ONLY) + { + // 1. draw solid HALF + renderer(DRAW_SOLID_HALF); + + // 2. render clipping plane here + renderer_clipping_plane(clipping_plane_rendering); } else { - rendering_program_face.enableAttributeArray("color"); + // 1. draw solid FOR ALL + renderer(DRAW_SOLID_ALL); } - glDrawArrays(GL_TRIANGLES, 0, static_cast(arrays[POS_COLORED_FACES].size()/3)); - vao[VAO_COLORED_FACES].release(); if (is_two_dimensional()) glPolygonOffset(offset_factor, offset_units); @@ -1260,6 +1336,13 @@ protected: } glEnable(GL_LIGHTING); } + + // Multiply matrix to get in the frame coordinate system. + // glMultMatrixd(manipulatedFrame()->matrix()); // Linker error + // Scale down the drawings + // glScalef(0.3f, 0.3f, 0.3f); // Linker error + // Draw an axis using the QGLViewer static function + // drawAxis(); } virtual void init() @@ -1294,6 +1377,32 @@ protected: bb.ymax(), bb.zmax())); + // init clipping plane array + auto generate_clipping_plane = [this](qreal size, int nbSubdivisions) + { + for (int i = 0; i <= nbSubdivisions; i++) + { + const float pos = float(size*(2.0*i/nbSubdivisions-1.0)); + arrays[POS_CLIPPING_PLANE].push_back(pos); + arrays[POS_CLIPPING_PLANE].push_back(float(-size)); + arrays[POS_CLIPPING_PLANE].push_back(0.f); + + arrays[POS_CLIPPING_PLANE].push_back(pos); + arrays[POS_CLIPPING_PLANE].push_back(float(+size)); + arrays[POS_CLIPPING_PLANE].push_back(0.f); + + arrays[POS_CLIPPING_PLANE].push_back(float(-size)); + arrays[POS_CLIPPING_PLANE].push_back(pos); + arrays[POS_CLIPPING_PLANE].push_back(0.f); + + arrays[POS_CLIPPING_PLANE].push_back(float(size)); + arrays[POS_CLIPPING_PLANE].push_back(pos); + arrays[POS_CLIPPING_PLANE].push_back(0.f); + } + }; + clipping_plane_rendering_size = ((bb.xmax() - bb.xmin()) + (bb.ymax() - bb.ymin()) + (bb.zmax() - bb.zmin())) / 3; + generate_clipping_plane(3.0 * clipping_plane_rendering_size, 30); + this->showEntireScene(); } @@ -1307,7 +1416,48 @@ protected: { const ::Qt::KeyboardModifiers modifiers = e->modifiers(); - if ((e->key()==::Qt::Key_E) && (modifiers==::Qt::NoButton)) + if ((e->key()==::Qt::Key_C) && (modifiers==::Qt::NoButton)) + { + if (!isOpenGL_4_3()) return; + if (!is_two_dimensional()) + { + // toggle clipping plane + m_use_clipping_plane = (m_use_clipping_plane + 1) % CLIPPING_PLANE_END_INDEX; + if (m_use_clipping_plane==CLIPPING_PLANE_OFF && m_frame_plane) + { + setManipulatedFrame(nullptr); + delete m_frame_plane; + m_frame_plane=nullptr; + } + else if (m_frame_plane==nullptr) + { + m_frame_plane=new CGAL::qglviewer::ManipulatedFrame; + setManipulatedFrame(m_frame_plane); + } + + switch(m_use_clipping_plane) + { + case CLIPPING_PLANE_OFF: displayMessage(QString("Draw clipping = flase")); break; + case CLIPPING_PLANE_SOLID_HALF_TRANSPARENT_HALF: clipping_plane_rendering=true; displayMessage(QString("Draw clipping = solid half & transparent half")); break; + case CLIPPING_PLANE_SOLID_HALF_WIRE_HALF: displayMessage(QString("Draw clipping = solid half & wireframe half")); break; + case CLIPPING_PLANE_SOLID_HALF_ONLY: displayMessage(QString("Draw clipping = solid half only")); break; + default: break; + } + update(); + } + } + + else if ((e->key()==::Qt::Key_C) && (modifiers==::Qt::AltModifier)) + { + if (!isOpenGL_4_3()) return; + if (m_use_clipping_plane!=CLIPPING_PLANE_OFF) + { + clipping_plane_rendering = !clipping_plane_rendering; + displayMessage(QString("Draw clipping plane=%1.").arg(clipping_plane_rendering?"true":"false")); + update(); + } + } + else if ((e->key()==::Qt::Key_E) && (modifiers==::Qt::NoButton)) { m_draw_edges=!m_draw_edges; displayMessage(QString("Draw edges=%1.").arg(m_draw_edges?"true":"false")); @@ -1536,6 +1686,17 @@ protected: bool m_draw_text; bool m_no_2D_mode; + enum { + CLIPPING_PLANE_OFF = 0, + CLIPPING_PLANE_SOLID_HALF_TRANSPARENT_HALF, + CLIPPING_PLANE_SOLID_HALF_WIRE_HALF, + CLIPPING_PLANE_SOLID_HALF_ONLY, + CLIPPING_PLANE_END_INDEX + }; + + int m_use_clipping_plane=CLIPPING_PLANE_OFF; + CGAL::qglviewer::ManipulatedFrame* m_frame_plane=nullptr; + double m_size_points; double m_size_edges; double m_size_rays; @@ -1568,6 +1729,7 @@ protected: POS_COLORED_LINES, POS_MONO_FACES, POS_COLORED_FACES, + POS_CLIPPING_PLANE, END_POS, BEGIN_COLOR=END_POS, COLOR_POINTS=BEGIN_COLOR, @@ -1596,6 +1758,7 @@ protected: Buffer_for_vao m_buffer_for_colored_lines; Buffer_for_vao m_buffer_for_mono_faces; Buffer_for_vao m_buffer_for_colored_faces; + Buffer_for_vao m_buffer_for_clipping_plane; static const unsigned int NB_VBO_BUFFERS=(END_POS-BEGIN_POS)+ (END_COLOR-BEGIN_COLOR)+2; // +2 for 2 vectors of normals @@ -1614,12 +1777,19 @@ protected: VAO_COLORED_LINES, VAO_MONO_FACES, VAO_COLORED_FACES, + VAO_CLIPPING_PLANE, NB_VAO_BUFFERS }; QOpenGLVertexArrayObject vao[NB_VAO_BUFFERS]; QOpenGLShaderProgram rendering_program_face; QOpenGLShaderProgram rendering_program_p_l; + QOpenGLShaderProgram rendering_program_clipping_plane; + + // variables for clipping plane + bool clipping_plane_rendering = true; // will be toggled when alt+c is pressed, which is used for indicating whether or not to render the clipping plane ; + float clipping_plane_rendering_transparency = 0.5f; // to what extent the transparent part should be rendered; + float clipping_plane_rendering_size; // to what extent the size of clipping plane should be rendered; std::vector > m_texts; }; diff --git a/GraphicsView/include/CGAL/Qt/constraint_impl.h b/GraphicsView/include/CGAL/Qt/constraint_impl.h index abb97f9d29d..513900a9fbd 100644 --- a/GraphicsView/include/CGAL/Qt/constraint_impl.h +++ b/GraphicsView/include/CGAL/Qt/constraint_impl.h @@ -59,7 +59,7 @@ void AxisPlaneConstraint::setTranslationConstraintDirection( if ((translationConstraintType() != AxisPlaneConstraint::FREE) && (translationConstraintType() != AxisPlaneConstraint::FORBIDDEN)) { const qreal norm = direction.norm(); - if (norm < 1E-8) { + if (norm == 0) { qWarning("AxisPlaneConstraint::setTranslationConstraintDir: null vector " "for translation constraint"); translationConstraintType_ = AxisPlaneConstraint::FREE; diff --git a/GraphicsView/include/CGAL/Qt/keyFrameInterpolator_impl.h b/GraphicsView/include/CGAL/Qt/keyFrameInterpolator_impl.h index fb0b2564ba6..eed29d31c14 100644 --- a/GraphicsView/include/CGAL/Qt/keyFrameInterpolator_impl.h +++ b/GraphicsView/include/CGAL/Qt/keyFrameInterpolator_impl.h @@ -318,7 +318,7 @@ qreal KeyFrameInterpolator::keyFrameTime(int index) const { /*! 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(). */ + fewer than 2 keyFrames. See also keyFrameTime(). */ CGAL_INLINE_FUNCTION qreal KeyFrameInterpolator::duration() const { return lastTime() - firstTime(); diff --git a/Hyperbolic_triangulation_2/demo/Hyperbolic_triangulation_2/CMakeLists.txt b/Hyperbolic_triangulation_2/demo/Hyperbolic_triangulation_2/CMakeLists.txt index 2dbde0e09b1..be9c9bbc48e 100644 --- a/Hyperbolic_triangulation_2/demo/Hyperbolic_triangulation_2/CMakeLists.txt +++ b/Hyperbolic_triangulation_2/demo/Hyperbolic_triangulation_2/CMakeLists.txt @@ -30,7 +30,12 @@ if(CGAL_Qt5_FOUND add_executable ( HDT2 HDT2.cpp ${CGAL_Qt5_RESOURCE_FILES} ${RESOURCE_FILES} ${UIS}) target_include_directories(HDT2 PRIVATE ./ ./include) add_to_cached_list( CGAL_EXECUTABLE_TARGETS HDT2 ) - target_link_libraries ( HDT2 CGAL::CGAL CGAL::CGAL_Qt5 CGAL::CGAL_Core Qt5::Widgets) + target_link_libraries ( HDT2 CGAL::CGAL CGAL::CGAL_Qt5 Qt5::Widgets) + if(CGAL_Core_FOUND) + target_link_libraries ( HDT2 CGAL::CGAL_Core) + else() + target_link_libraries ( HDT2 ${LEDA_LIBRARIES}) + endif() else() message( STATUS diff --git a/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/CGAL/Hyperbolic_Delaunay_triangulation_2.h b/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/CGAL/Hyperbolic_Delaunay_triangulation_2.h index c07639e7c08..e91823b0dae 100644 --- a/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/CGAL/Hyperbolic_Delaunay_triangulation_2.h +++ b/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/CGAL/Hyperbolic_Delaunay_triangulation_2.h @@ -11,16 +11,18 @@ The class `Hyperbolic_Delaunay_triangulation_2` is the main class of the 2D Hype It is designed to represent Delaunay triangulations of sets of points in the hyperbolic plane. The hyperbolic plane is represented in the Poincaré disk model. -\tparam Gt must be a model of `HyperbolicDelaunayTriangulationTraits_2`. -\tparam Tds must be a model of `TriangulationDataStructure_2`. By default, this parameter is instantiated with -`Triangulation_data_structure_2< Triangulation_vertex_base_2, Hyperbolic_triangulation_face_base_2 >` +\tparam Gt is the geometric traits class and must be a model of `HyperbolicDelaunayTriangulationTraits_2`. +\tparam Tds is the triangulation graph data structure and must be a model of `TriangulationDataStructure_2` +whose vertex and face are models of `TriangulationVertexBase_2` and `HyperbolicTriangulationFaceBase_2`, respectively. +It defaults to: +\code +CGAL::Triangulation_data_structure_2< + CGAL::Triangulation_vertex_base_2, + CGAL::Hyperbolic_triangulation_face_base_2 > +\endcode -\sa `HyperbolicDelaunayTriangulationTraits_2` -\sa `TriangulationDataStructure_2` \sa `Delaunay_triangulation_2` - */ - template < class Gt, class Tds > class Hyperbolic_Delaunay_triangulation_2: private Delaunay_triangulation_2 { diff --git a/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/Concepts/HyperbolicTriangulationFaceBase_2.h b/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/Concepts/HyperbolicTriangulationFaceBase_2.h index 744a7872854..45675b33aa7 100644 --- a/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/Concepts/HyperbolicTriangulationFaceBase_2.h +++ b/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/Concepts/HyperbolicTriangulationFaceBase_2.h @@ -7,7 +7,7 @@ \cgalRefines TriangulationFaceBase_2 -The concept HyperbolicTriangulationFaceBase_2 describes the requirements for the base +The concept `HyperbolicTriangulationFaceBase_2` describes the requirements for the base face class of a hyperbolic triangulation data structure. This concept provides an interface for the functionality needed in faces to compute diff --git a/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/Hyperbolic_triangulation_2.txt b/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/Hyperbolic_triangulation_2.txt index 6c29153fc50..6ef7fadd068 100644 --- a/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/Hyperbolic_triangulation_2.txt +++ b/Hyperbolic_triangulation_2/doc/Hyperbolic_triangulation_2/Hyperbolic_triangulation_2.txt @@ -104,11 +104,11 @@ parameters: primitives. The requirements on this first template parameter are described by the concept `HyperbolicDelaunayTriangulationTraits_2`, which refines - `DelaunayTriangulationTraits_2`. + `DelaunayTriangulationTraits_2`.
  • A triangulation data structure parameter, for which the - requirements are described by the concept - `TriangulationDataStructure_2`. The default for this second template parameter - is `Triangulation_data_structure_2< Triangulation_vertex_base_2, Hyperbolic_triangulation_face_base_2 >`. + requirements are described by the concept `TriangulationDataStructure_2`. + The vertex and face of this triangulation data structure must be models of + the concepts `TriangulationVertexBase_2` and `HyperbolicTriangulationFaceBase_2`, respectively.
  • Two models of the concept `HyperbolicDelaunayTriangulationTraits_2` diff --git a/Installation/CHANGES.md b/Installation/CHANGES.md index 9a02a6ba2d0..9ef17a23944 100644 --- a/Installation/CHANGES.md +++ b/Installation/CHANGES.md @@ -25,9 +25,25 @@ A comprehensive list of the supported file formats is available in the Stream_su - Added a filtering mechanism so that costly tests get only applied to the next candidate for the edge collapse. - Added the class `Polyhedral_envelope_filter` that enables to perform mesh simplification inside a polyhedral envelope of the input mesh. +### Surface Mesh Topology +- Added the function `CGAL::Surface_mesh_topology::Curves_on_surface_topology::is_homotopic_to_simple_cycle()`, which can be used to determine whehter a closed path + on a surface mesh can be continously transformed to a cycle without self intersection. + ### 2D Regularized Boolean Set Operations - Added documentation for the free functions `oriented_side(const Point_2& p, ....)` that accept a point and a polygon, and improved the documentation of all other functions +### [2D Polyline Simplification](https://doc.cgal.org/5.3/Manual/packages.html#PkgPolylineSimplification2) +- When polylines have common subsequences of vertices these subsequences may be simplifified simultaneously. + +### [2D and 3D Alpha Shapes](https://doc.cgal.org/5.3/Manual/packages.html#PkgAlphaShapes2) +- The following deprecated classes have been removed: `Alpha_shape_euclidean_traits_2`, + `Weighted_alpha_shape_euclidean_traits_2`, `Alpha_shape_euclidean_traits_3`, and + `Weighted_alpha_shape_euclidean_traits_3`. All CGAL kernel can be used directly as models + of the concepts of the 2D and 3D Alpha Shape packages. + +### [dD Triangulations](https://doc.cgal.org/5.3/Manual/packages.html#PkgTriangulations) +- Added the function `insert_if_in_star()` to the class `CGAL::Regular_triangulation`, which enables users to insert a point `p` in a regular triangulation on the condition that `p` appears post-insertion in the star of a user-specified, existing vertex. + [Release 5.2](https://github.com/CGAL/cgal/releases/tag/v5.2) ----------- diff --git a/Installation/test/Installation/CMakeLists.txt b/Installation/test/Installation/CMakeLists.txt index dd7854b8080..684b9f40731 100644 --- a/Installation/test/Installation/CMakeLists.txt +++ b/Installation/test/Installation/CMakeLists.txt @@ -56,7 +56,7 @@ endif() create_link_to_program(CGAL) -if(WITH_CGAL_Core) +if ( CGAL_Core_FOUND ) create_link_to_program(CGAL_Core) endif() @@ -64,6 +64,7 @@ if(WITH_CGAL_ImageIO) create_link_to_program(CGAL_ImageIO) endif() + if(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL Windows) add_executable(display_dll_version_info display_dll_version_info.cpp) target_link_libraries(display_dll_version_info version) diff --git a/Interpolation/TODO b/Interpolation/TODO index b1cde04626a..574426e92ef 100644 --- a/Interpolation/TODO +++ b/Interpolation/TODO @@ -181,6 +181,6 @@ long and hold to much information at once for a manual. For example: predicate you have to read at least twice before getting the meaning. More, but simpler sentences would do a lot, especially as people look up the manual on the web. Partly it just simply reads more like a -scientific paper then like a manual. +scientific paper than like a manual. =================== diff --git a/Intersections_3/include/CGAL/Intersections_3/Line_3_Plane_3.h b/Intersections_3/include/CGAL/Intersections_3/Line_3_Plane_3.h index 5dc93e65edd..49f64fa5fca 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Line_3_Plane_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Line_3_Plane_3.h @@ -26,17 +26,17 @@ CGAL_DO_INTERSECT_FUNCTION(Plane_3, Line_3, 3) template < class K > inline boost::optional -intersection_point(const Plane_3& plane, const Line_3& line) +intersection_point_for_polyhedral_envelope(const Plane_3& plane, const Line_3& line) { - return K().intersect_point_3_object()(plane, line); + return K().intersect_point_3_for_polyhedral_envelope_object()(plane, line); } template < class K > inline boost::optional - intersection_point(const Line_3& line, const Plane_3& plane) + intersection_point_for_polyhedral_envelope(const Line_3& line, const Plane_3& plane) { - return K().intersect_point_3_object()(plane, line); + return K().intersect_point_3_for_polyhedral_envelope_object()(plane, line); } } diff --git a/Intersections_3/include/CGAL/Intersections_3/Plane_3_Plane_3.h b/Intersections_3/include/CGAL/Intersections_3/Plane_3_Plane_3.h index 5f3a176056c..7f82f23b740 100644 --- a/Intersections_3/include/CGAL/Intersections_3/Plane_3_Plane_3.h +++ b/Intersections_3/include/CGAL/Intersections_3/Plane_3_Plane_3.h @@ -26,9 +26,9 @@ CGAL_DO_INTERSECT_FUNCTION_SELF(Plane_3, 3) template < class K > inline boost::optional -intersection_point(const Plane_3& p0, const Plane_3& p1, const Plane_3& p2) +intersection_point_for_polyhedral_envelope(const Plane_3& p0, const Plane_3& p1, const Plane_3& p2) { - return K().intersect_point_3_object()(p0, p1, p2); + return K().intersect_point_3_for_polyhedral_envelope_object()(p0, p1, p2); } } diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h index 977c7dcc584..270693f2fb9 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Iso_cuboid_3_Plane_3_intersection.h @@ -8,7 +8,7 @@ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // -// Author(s) : Maxime Gimeno +// Author(s) : Sebastien Loriot and Andreas Fabri // #ifndef CGAL_INTERNAL_INTERSECTIONS_3_ISO_CUBOID_3_PLANE_3_INTERSECTION_H @@ -16,320 +16,195 @@ #include #include +#include -#include -#include -#include - -#include +#include +#include namespace CGAL { namespace Intersections { namespace internal { -template -void filter_points(std::vector& input, - std::vector& output) -{ - std::sort(input.begin(), input.end()); - auto last = std::unique(input.begin(), input.end()); - input.erase(last, input.end()); - output = std::move(input); -} - -//Tetrahedron_3 Line_3 +//Iso_cuboid_3 Plane_3 template typename Intersection_traits::result_type intersection( - const typename K::Iso_cuboid_3 &cub, - const typename K::Plane_3 &pl, - const K& k) + const typename K::Iso_cuboid_3& cub, + const typename K::Plane_3& plane, + const K& k) { typedef typename K::Point_3 Point_3; - typedef typename K::Segment_3 Segment_3; - typedef typename K::Line_3 Line_3; - typedef typename K::Plane_3 Plane_3; - typedef std::vector Poly; + typedef typename Intersection_traits::result_type result_type; + typename K::Oriented_side_3 oriented_side = k.oriented_side_3_object(); - typedef typename Intersection_traits, - CGAL::Plane_3 >::result_type result_type; + std::vector corners(8); + corners.reserve(14); // 8 corners + up to 6 polygon points + corners[0] = cub[0]; + corners[1] = cub[3]; + corners[2] = cub[2]; + corners[3] = cub[1]; + corners[4] = cub[5]; + corners[5] = cub[4]; + corners[6] = cub[7]; + corners[7] = cub[6]; - typedef typename Intersection_traits, - CGAL::Plane_3 >::result_type Inter_type; + const std::array orientations { { + oriented_side(plane, corners[0]), + oriented_side(plane, corners[1]), + oriented_side(plane, corners[2]), + oriented_side(plane, corners[3]), + oriented_side(plane, corners[4]), + oriented_side(plane, corners[5]), + oriented_side(plane, corners[6]), + oriented_side(plane, corners[7]) + } }; - std::vector edges; - edges.reserve(12); + // description of faces of the bbox + constexpr std::array face_indices + { { 0, 1, 2, 3, + 2, 1, 5, 6, + 3, 2, 6, 7, + 1, 0, 4, 5, + 4, 0, 3, 7, + 6, 5, 4, 7 } }; - //get all edges of cub - for(int i=0; i< 4; ++i) - edges.emplace_back(cub.vertex(i), cub.vertex((i+1)%4)); - for(int i=0; i < 4; ++i) - edges.emplace_back(cub.vertex(i+4), cub.vertex((i+1)%4+4)); - for(int i=0; i < 4; ++i) - edges.emplace_back(cub.vertex(i), cub.vertex((i+1)%4+4)); + constexpr std::array edge_indices + { { 0, 1, 2, 3, + 1, 4, 5, 6, + 2, 6, 7, 8, + 0, 9, 10, 4, + 9, 3, 8, 11, + 5, 10, 11, 7 } }; - //get all intersections between pl and cub edges - std::vector segments; - std::vector points; + std::array edge_ipt_id; + edge_ipt_id.fill(-1); - for(int i=0; i < 12; ++i) + auto inter_pt_index = + [&plane, &corners, &edge_ipt_id](int i, int j, int edge_id) { - // Intersect_3 checks the orientation of the segment's extremities to avoid actually computing - // the intersection if possible - Inter_type inter = typename K::Intersect_3()(pl, edges[i]); - if(inter) + if (edge_ipt_id[edge_id]==-1) { - if(const Segment_3* seg = boost::get(&*inter)) - segments.push_back(*seg); - else if(const Point_3* p = boost::get(&*inter)) - points.push_back(*p); + edge_ipt_id[edge_id] = static_cast (corners.size()); + corners.push_back(typename K::Construct_plane_line_intersection_point_3() + (plane, corners[i], corners[j])); } - } - if(segments.empty() && points.empty()) - return result_type(); + return edge_ipt_id[edge_id]; + }; - switch(segments.size()) + bool all_in = true; + bool all_out = true; + + std::vector> neighbor_ids(14, {-1,-1}); + + auto add_neighbor = [&neighbor_ids](int i, int j) { - case 0: - //points dealt with later - break; - case 1: - { - //adj to an edge - if(points.size() == 4) + if (neighbor_ids[i][0] == -1 ) { + neighbor_ids[i][0] = j; + } + else { + if (neighbor_ids[i][0]!=j && neighbor_ids[i][1]==-1) { - return result_type(std::forward(segments.front())); + neighbor_ids[i][1] = j; } - //plane intersecting through an edge (not 2) - else - { - Poly res(4); - const Segment_3& entry_seg(segments.front()); - Point_3 p1, p2; - bool p1_found(false), - p2_found(false); + } + }; - for(const Point_3& p : points) + int start_id = -1; + int solo_id = -1; + // for each face of the bbox, we look for intersection of the plane with its edges + std::vector ids; + for (int i = 0; i < 6; ++i) + { + ids.clear(); + for (int k = 0; k < 4; ++k) + { + + int current_id = face_indices[4 * i + k]; + int next_id = face_indices[4 * i + (k + 1) % 4]; + int edge_id = edge_indices[4 * i + k]; + + switch (orientations[current_id]) + { + case ON_NEGATIVE_SIDE: { - if(!k.equal_3_object()(entry_seg.source(), p) - && ! k.equal_3_object()(entry_seg.target(), p)) + all_out = false; + // check for intersection of the edge + if (orientations[next_id] == ON_POSITIVE_SIDE) { - if(!p1_found) - { - p1 = p; - p1_found = true; - } - else { - p2 = p; - p2_found = true; - break; - } + ids.push_back( + inter_pt_index(current_id, next_id, edge_id)); } - } - CGAL_USE(p2_found); - CGAL_assertion(p1_found && p2_found); - res[0] = entry_seg.target(); - res[1] = p2; - res[2] = p1; - res[3] = entry_seg.source(); - - typename K::Coplanar_orientation_3 coplanar_orientation = - k.coplanar_orientation_3_object(); - - if( coplanar_orientation(res[0], res[1], res[2]) - != coplanar_orientation(res[0], res[1], res[3])) - { - std::swap(res[1], res[2]); - } - - return result_type(std::forward(res)); - } - } - break; - - case 2: //intersects diagonally - { - Poly res(4); - Segment_3 &front(segments.front()), - &back(segments.back()); - res[0] = front.target(); - res[1] = back.target(); - res[2] = back.source(); - res[3] = front.source(); - typename K::Coplanar_orientation_3 coplanar_orientation = - k.coplanar_orientation_3_object(); - - if( coplanar_orientation(res[0], res[1], res[2]) - != coplanar_orientation(res[0], res[1], res[3])) - { - std::swap(res[1], res[2]); - } - - return result_type(std::forward(res)); - } - break; - case 4: // intersects a face - { - Poly res; - res.reserve(4); - typename K::Has_on_3 has_on; - if(has_on(pl, cub.vertex(0)) - && has_on(pl, cub.vertex(5)) - && has_on(pl, cub.vertex(4))) - { - res.push_back(cub.vertex(0)); - res.push_back(cub.vertex(5)); - res.push_back(cub.vertex(4)); - res.push_back(cub.vertex(3)); - } - else if(has_on(pl, cub.vertex(0)) - && has_on(pl, cub.vertex(1)) - && has_on(pl, cub.vertex(6))) - { - res.push_back(cub.vertex(0)); - res.push_back(cub.vertex(1)); - res.push_back(cub.vertex(6)); - res.push_back(cub.vertex(5)); - - } - else if(has_on(pl, cub.vertex(1)) - && has_on(pl, cub.vertex(2)) - && has_on(pl, cub.vertex(7))) - { - res.push_back(cub.vertex(1)); - res.push_back(cub.vertex(2)); - res.push_back(cub.vertex(7)); - res.push_back(cub.vertex(6)); - } - else if(has_on(pl, cub.vertex(2)) - && has_on(pl, cub.vertex(3)) - && has_on(pl, cub.vertex(4))) - { - res.push_back(cub.vertex(2)); - res.push_back(cub.vertex(3)); - res.push_back(cub.vertex(4)); - res.push_back(cub.vertex(7)); - } - else if(has_on(pl, cub.vertex(6)) - && has_on(pl, cub.vertex(7)) - && has_on(pl, cub.vertex(4))) - { - res.push_back(cub.vertex(6)); - res.push_back(cub.vertex(7)); - res.push_back(cub.vertex(4)); - res.push_back(cub.vertex(5)); - } - else if(has_on(pl, cub.vertex(2)) - && has_on(pl, cub.vertex(1)) - && has_on(pl, cub.vertex(0))) - { - res.push_back(cub.vertex(2)); - res.push_back(cub.vertex(1)); - res.push_back(cub.vertex(0)); - res.push_back(cub.vertex(3)); - } - return result_type(std::forward(res)); - } - break; - default: - break; - } - - Poly filtered_points; - filter_points(points, filtered_points); - - //adjacent to a vertex - if(filtered_points.size() == 1) - { - return result_type(std::forward(filtered_points.front())); - } - - //get intersections between pl and each face -> line. Foreach line, creates segment with points. Then use helper_function to recover polygon. - typedef typename Intersection_traits, - CGAL::Plane_3 >::result_type Pl_pl_type; - - std::vector plane_intersections; - Pl_pl_type pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0), - cub.vertex(1), - cub.vertex(5))); - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0), - cub.vertex(3), - cub.vertex(4))); - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(0), - cub.vertex(1), - cub.vertex(3))); - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7), - cub.vertex(6), - cub.vertex(1))); - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7), - cub.vertex(4), - cub.vertex(3))); - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - pl_inter = CGAL::intersection(pl, Plane_3(cub.vertex(7), - cub.vertex(6), - cub.vertex(4))); - if(const Line_3* line = boost::get(&*pl_inter)){ - plane_intersections.push_back(*line); - } - - std::list tmp_segs; - for(const auto& line : plane_intersections) - { - bool first_found = false; - Point_3 first_p; - typename K::Has_on_3 has_on; - for(const auto &p : filtered_points) - { - if(has_on(line, p)) - { - if(!first_found) - { - first_found = true; - first_p = p; - } - else - { - tmp_segs.emplace_back(first_p, p); break; } + case ON_POSITIVE_SIDE: + { + all_in = false; + // check for intersection of the edge + if (orientations[next_id] == ON_NEGATIVE_SIDE) + { + ids.push_back(inter_pt_index(current_id, next_id, edge_id)); + } + break; + } + case ON_ORIENTED_BOUNDARY: + { + all_in = all_out = false; + ids.push_back(current_id); + } } } + + switch (ids.size()) + { + case 4: + { + std::vector res({ corners[ids[0]], + corners[ids[1]], + corners[ids[2]], + corners[ids[3]] }); + return result_type(res); + } + case 2: + { + if (start_id == -1) start_id = ids[0]; + add_neighbor(ids[0], ids[1]); + add_neighbor(ids[1], ids[0]); + break; + } + case 1: + solo_id = ids[0]; + default: + break; + } } - if(tmp_segs.size() < 3) - return result_type(); + if (all_in || all_out) return boost::none; + if (start_id == -1) return { result_type(corners[solo_id]) }; - std::list tmp_pts; - fill_points_list(tmp_segs,tmp_pts); - - Poly res; - for(const auto& p : tmp_pts) - res.push_back(p); - - if(res.size() == 3){ - typename K::Triangle_3 tr(res[0], res[1], res[2]); - return result_type(std::forward(tr)); - } - else - { - return result_type(std::forward(res)); - } + int prv_id = -1; + int cur_id = start_id; + std::vector res; + res.reserve(6); + do { + res.push_back(corners[cur_id]); + int nxt_id = neighbor_ids[cur_id][0] == prv_id + ? neighbor_ids[cur_id][1] + : neighbor_ids[cur_id][0]; + if (nxt_id == -1 || nxt_id == start_id){ + if(res.size() == 2){ + typename K::Segment_3 seg(res[0], res[1]); + return result_type(seg); + } + if(res.size() == 3){ + typename K::Triangle_3 tr(res[0], res[1], res[2]); + return result_type(tr); + } + return result_type(res); + } + prv_id = cur_id; + cur_id = nxt_id; + } while (true); } template diff --git a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h index fa55cb268f2..498ab69a56e 100644 --- a/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h +++ b/Intersections_3/include/CGAL/Intersections_3/internal/Tetrahedron_3_Plane_3_intersection.h @@ -32,101 +32,170 @@ template typename Intersection_traits::result_type intersection( const typename K::Tetrahedron_3 &tet, - const typename K::Plane_3 &pl, - const K&) + const typename K::Plane_3 &plane, + const K& k) { - typedef typename Intersection_traits::result_type result_type; + typedef typename K::Point_3 Point_3; + typedef typename K::Triangle_3 Triangle_3; + typedef typename Intersection_traits::result_type result_type; + typename K::Oriented_side_3 oriented_side = k.oriented_side_3_object(); - typedef typename Intersection_traits::result_type Inter_type; + std::vector corners(4); + corners.reserve(8); // 4 corners + up to 4 polygon points + corners[0] = tet[0]; + corners[1] = tet[1]; + corners[2] = tet[2]; + corners[3] = tet[3]; - typedef typename K::Segment_3 Segment_3; - Inter_type intersections[4]; - int p_id = -1; - std::vector points; - std::vector segments; - for(int i = 0; i < 4; ++i) + const std::array orientations { { + oriented_side(plane, corners[0]), + oriented_side(plane, corners[1]), + oriented_side(plane, corners[2]), + oriented_side(plane, corners[3]) + } }; + + // description of faces of the bbox + constexpr std::array face_indices + { { 0, 1, 2, + 0, 1, 3, + 1, 2, 3, + 2, 0, 3 } }; + + constexpr std::array edge_indices + { { 0, 1, 2, + 0, 3, 5, + 1, 4, 3, + 2, 5, 4 } }; + + std::array edge_ipt_id; + edge_ipt_id.fill(-1); + + auto inter_pt_index = + [&plane, &corners, &edge_ipt_id](int i, int j, int edge_id) { - const typename K::Triangle_3 triangle(tet.vertex((i+1)%4), - tet.vertex((i+2)%4), - tet.vertex((i+3)%4)); - intersections[i] = typename K::Intersect_3()(pl, triangle); - if(intersections[i]){ - if(const typename K::Triangle_3* tr = boost::get(&*intersections[i])) + if (edge_ipt_id[edge_id]==-1) + { + edge_ipt_id[edge_id] = static_cast (corners.size()); + corners.push_back(typename K::Construct_plane_line_intersection_point_3() + (plane, corners[i], corners[j])); + } + + return edge_ipt_id[edge_id]; + }; + + bool all_in = true; + bool all_out = true; + + std::vector> neighbor_ids(8, {-1,-1}); + + auto add_neighbor = [&neighbor_ids](int i, int j) + { + if (neighbor_ids[i][0] == -1 ) { + neighbor_ids[i][0] = j; + } + else { + if (neighbor_ids[i][0]!=j && neighbor_ids[i][1]==-1) { - typename K::Triangle_3 res = *tr; - return result_type(std::forward(res)); - } - else if( const Segment_3* s - = boost::get(&*intersections[i])) - { - segments.push_back(*s); - } - else if( const typename K::Point_3* p - = boost::get(&*intersections[i])) - { - points.push_back(*p); - p_id = i; + neighbor_ids[i][1] = j; } } - } - CGAL_assertion(segments.size() != 1); + }; - switch(segments.size()) + int start_id = -1; + int solo_id = -1; + // for each face of the bbox, we look for intersection of the plane with its edges + std::vector ids; + for (int i = 0; i < 4; ++i) { - case 0: - { - if(p_id == -1) - return result_type(); - else + ids.clear(); + for (int k = 0; k < 3; ++k) { - typename K::Point_3 p - = *boost::get(&*intersections[p_id]); - return result_type(std::forward(p)); + int current_id = face_indices[3 * i + k]; + int next_id = face_indices[3 * i + (k + 1) % 3]; + int edge_id = edge_indices[3 * i + k]; + + switch (orientations[current_id]) + { + case ON_NEGATIVE_SIDE: + { + all_out = false; + // check for intersection of the edge + if (orientations[next_id] == ON_POSITIVE_SIDE) + { + ids.push_back( + inter_pt_index(current_id, next_id, edge_id)); + } + break; + } + case ON_POSITIVE_SIDE: + { + all_in = false; + // check for intersection of the edge + if (orientations[next_id] == ON_NEGATIVE_SIDE) + { + ids.push_back(inter_pt_index(current_id, next_id, edge_id)); + } + break; + } + case ON_ORIENTED_BOUNDARY: + { + all_in = all_out = false; + ids.push_back(current_id); + } + } } - } - break; - case 2: - { - return result_type(std::forward(segments.back())); - } - break; - default: - { - std::set all_points; - for (const auto& s : segments) + + switch (ids.size()) { - all_points.insert(s.source()); - all_points.insert(s.target()); - } - if(all_points.size() == 3) - { - auto p_it = all_points.begin(); - ++p_it; - typename K::Point_3 mid_point = *p_it; - ++p_it; - typename K::Triangle_3 result(*all_points.begin(), mid_point, *p_it ); - return result_type(std::forward(result)); - } - else //size = 4 - { - std::list segs(segments.begin(), segments.end()); - std::list tmp; - fill_points_list(segs, tmp); - std::vector res; - for( const auto& p : tmp) - res.push_back(p); - return result_type(std::forward >(res)); + case 3: + { + Triangle_3 res(corners[ids[0]], + corners[ids[1]], + corners[ids[2]]); + return result_type(res); + } + case 2: + { + if (start_id == -1) start_id = ids[0]; + add_neighbor(ids[0], ids[1]); + add_neighbor(ids[1], ids[0]); + break; + } + case 1: + solo_id = ids[0]; + default: + break; } } - break; - } - CGAL_assertion(false); - return result_type(); + + if (all_in || all_out) return boost::none; + if (start_id == -1) return { result_type(corners[solo_id]) }; + + int prv_id = -1; + int cur_id = start_id; + std::vector res; + res.reserve(4); + do { + res.push_back(corners[cur_id]); + int nxt_id = neighbor_ids[cur_id][0] == prv_id + ? neighbor_ids[cur_id][1] + : neighbor_ids[cur_id][0]; + if (nxt_id == -1 || nxt_id == start_id){ + if(res.size() == 2){ + typename K::Segment_3 seg(res[0], res[1]); + return result_type(seg); + } + if(res.size() == 3){ + typename K::Triangle_3 tr(res[0], res[1], res[2]); + return result_type(tr); + } + return result_type(res); + } + prv_id = cur_id; + cur_id = nxt_id; + } while (true); + } template diff --git a/Intersections_3/test/Intersections_3/issue_5428.cpp b/Intersections_3/test/Intersections_3/issue_5428.cpp new file mode 100644 index 00000000000..ea6dc18cd0f --- /dev/null +++ b/Intersections_3/test/Intersections_3/issue_5428.cpp @@ -0,0 +1,24 @@ +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel EPICK; + +typedef EPICK::Point_3 Point; + +int main() +{ + EPICK::Plane_3 pl(Point(0, 0, 0), Point(1, 0, 0), Point(0, 1, 0)); + + std::vector pts; + pts.push_back(Point(-10,-10,-10)); + pts.push_back(Point(10,10,10)); + CGAL::Bbox_3 cub = CGAL::bbox_3(pts.begin(), pts.end()); + + auto result = intersection(cub,pl); + + const std::vector* res = boost::get >(&*result); + for (Point p : *res) { + std::cout << p << std::endl; + } + + return 0; +} diff --git a/Intersections_3/test/Intersections_3/test_intersections_3.cpp b/Intersections_3/test/Intersections_3/test_intersections_3.cpp index 7247a3c472e..f93026b3d11 100644 --- a/Intersections_3/test/Intersections_3/test_intersections_3.cpp +++ b/Intersections_3/test/Intersections_3/test_intersections_3.cpp @@ -672,7 +672,8 @@ struct Test { P(0,1,0)); check_intersection (tet, Pl(P(0,0.5,0), P(1,0.5,-5), P(0.5,0.5,0.5)), - Tr(P(0.5,0.5,0), P(0,0.5,0), P(0,0.5,0.5))); + Tr(P(0, 0.5, 0), P(0.5,0.5,0), P(0,0.5,0.5))); + Pl pl(P(0,0.9,0), P(0.9,0,0), P(0.9,0.01,0.06)); typedef typename CGAL::Intersection_traits >(&*res); assert(poly != nullptr); assert(poly->size() == 4); @@ -940,8 +942,8 @@ struct Test { check_intersection (cub, Pl(P(2, 1.66, 2), P(1.66,2,2), P(2,2,1.66)), - Tr(P(2, 2, 1.66), - P(1.66,2,2), + Tr(P(1.66,2,2), + P(2, 2, 1.66), P(2,1.66,2))); //other edge @@ -1100,7 +1102,7 @@ struct Test { //edge check_intersection (cub, Pl(P(1,1,1), P(1,2,1), P(1.5,0,0)), - S(P(1,2,1), P(1,1,1))); + S(P(1,1,1), P(1,2,1))); //face typedef typename CGAL::Intersection_traits #include -#include - typedef CGAL::Exact_predicates_exact_constructions_kernel K; typedef K::Point_2 Point; typedef K::Segment_2 Segment; diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index b462f6ef001..1d698f65b6e 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -3568,8 +3568,12 @@ namespace CommonKernelFunctors { }; + // This functor is not part of the documented Kernel API, but an implementation detail + // of Polygon_mesh_processing::Polyhedral_envelope + // When used with the Lazy_kernel (that is Epeck) the returned point + // is a singleton (so its coordinates will be changed by another call). template - class Intersect_point_3 + class Intersect_point_3_for_polyhedral_envelope { public: typedef typename K::Point_3 Point_3; @@ -3787,6 +3791,7 @@ namespace CommonKernelFunctors { class Oriented_side_3 { typedef typename K::Point_3 Point_3; + typedef typename K::Vector_3 Vector_3; typedef typename K::Tetrahedron_3 Tetrahedron_3; typedef typename K::Plane_3 Plane_3; typedef typename K::Sphere_3 Sphere_3; @@ -3801,6 +3806,12 @@ namespace CommonKernelFunctors { operator()( const Plane_3& pl, const Point_3& p) const { return pl.rep().oriented_side(p); } + result_type + operator()( const Point_3& plane_pt, const Vector_3& plane_normal, const Point_3& query) const + { + return typename K::Construct_plane_3()(plane_pt, plane_normal).rep().oriented_side(query); + } + result_type operator()( const Tetrahedron_3& t, const Point_3& p) const { return t.rep().oriented_side(p); } diff --git a/Kernel_23/include/CGAL/Kernel/interface_macros.h b/Kernel_23/include/CGAL/Kernel/interface_macros.h index 43f5ff7a2f7..a4caf77e7be 100644 --- a/Kernel_23/include/CGAL/Kernel/interface_macros.h +++ b/Kernel_23/include/CGAL/Kernel/interface_macros.h @@ -542,8 +542,8 @@ CGAL_Kernel_cons(Intersect_2, intersect_2_object) CGAL_Kernel_cons(Intersect_3, intersect_3_object) -CGAL_Kernel_cons(Intersect_point_3, - intersect_point_3_object) +CGAL_Kernel_cons(Intersect_point_3_for_polyhedral_envelope, + intersect_point_3_for_polyhedral_envelope_object) CGAL_Kernel_pred(Is_degenerate_2, is_degenerate_2_object) CGAL_Kernel_pred_RT(Is_degenerate_3, diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_test_new_3.h b/Kernel_23/test/Kernel_23/include/CGAL/_test_new_3.h index 540eafe080f..0beec86c962 100644 --- a/Kernel_23/test/Kernel_23/include/CGAL/_test_new_3.h +++ b/Kernel_23/test/Kernel_23/include/CGAL/_test_new_3.h @@ -747,6 +747,7 @@ test_new_3(const R& rep) = rep.oriented_side_3_object(); Oriented_side tmp39 = oriented_side(h2,p2); tmp39 = oriented_side(sp9,p2); + tmp39 = oriented_side(p2,v1,p2); (void) tmp39; typename R::Bounded_side_3 bounded_side diff --git a/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h b/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h index 3794119da67..12ff9aeb723 100644 --- a/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h +++ b/Kernel_d/include/CGAL/Kernel_d/Iso_box_d.h @@ -25,6 +25,7 @@ #include #include #include +#include namespace CGAL { @@ -41,9 +42,11 @@ namespace CGAL { typedef typename Point::Cartesian_const_iterator Iterator; typedef Cartesian_iterator Self; - typedef typename Functor::result_type value_type; - typedef value_type& reference; - typedef value_type* pointer; + typedef decltype(std::declval()( + *std::declval(), + *std::declval())) value_type; + typedef value_type reference; + typedef const value_type* pointer; typedef std::ptrdiff_t difference_type; typedef std::input_iterator_tag iterator_category; @@ -89,7 +92,7 @@ namespace CGAL { return tmp; } - value_type operator*() const { return f(*pb, *qb); } + reference operator*() const { return f(*pb, *qb); } pointer operator->() const { return &(**this); } const Functor& functor() const { return f; } @@ -118,9 +121,12 @@ namespace CGAL { typedef typename Point::Homogeneous_const_iterator Iterator; typedef Homogeneous_iterator Self; - typedef typename Functor::result_type value_type; - typedef value_type& reference; - typedef value_type* pointer; + typedef typename Kernel_traits::Kernel::RT RT; + typedef decltype(std::declval()( + *std::declval() * std::declval(), + *std::declval() * std::declval())) value_type; + typedef value_type reference; + typedef const value_type* pointer; typedef std::ptrdiff_t difference_type; typedef std::input_iterator_tag iterator_category; @@ -128,7 +134,6 @@ namespace CGAL { Iterator pb, qb; Functor f; - typedef typename Kernel_traits::Kernel::RT RT; RT hp, hq; // homogenizing coordinates public: diff --git a/Linear_cell_complex/include/CGAL/Linear_cell_complex_constructors.h b/Linear_cell_complex/include/CGAL/Linear_cell_complex_constructors.h index 1505ca79733..95ec3e88a2b 100644 --- a/Linear_cell_complex/include/CGAL/Linear_cell_complex_constructors.h +++ b/Linear_cell_complex/include/CGAL/Linear_cell_complex_constructors.h @@ -205,7 +205,7 @@ namespace CGAL { std::cerr << " " << std::endl; std::cerr << "Polyhedron_scan_OFF::" << std::endl; std::cerr << "operator()(): input error: facet " << i - << " has less than 3 vertices." << std::endl; + << " has fewer than 3 vertices." << std::endl; } B.rollback(); in.clear( std::ios::badbit); diff --git a/Maintenance/public_release/scripts/github-release-upload b/Maintenance/public_release/scripts/github-release-upload index 760916fd838..8a253f112bd 100755 --- a/Maintenance/public_release/scripts/github-release-upload +++ b/Maintenance/public_release/scripts/github-release-upload @@ -3,11 +3,8 @@ # Should be run in the directory with the release files, and named after # the release name, like "CGAL-4.9.1". -# Use github-release from -# https://github.com/aktau/github-release +release=${${PWD:t}/CGAL-/} +tag=v${release} -source $HOME/private/github-token.txt - -for f in *.(zip|xz|txt|exe); do - github-release upload -u CGAL -r cgal -t v${${PWD:t}/CGAL-/} --name $f -f $f; -done +gh release upload "$tag" *.(zip|xz|txt|exe) -R CGAL/cgal +gh release upload "$tag" CGAL-${release}-win64-auxiliary-libraries-gmp-mpfr.zip'#GMP and MPFR libraries, for Windows 64bits' -R CGAL/cgal --clobber diff --git a/Maintenance/public_release/scripts/prepare_release b/Maintenance/public_release/scripts/prepare_release index 639f9fe5c63..889c7e99da3 100755 --- a/Maintenance/public_release/scripts/prepare_release +++ b/Maintenance/public_release/scripts/prepare_release @@ -81,6 +81,10 @@ pushd "$DEST_DIR/doc_html" zip -q -r ../cgal_manual.zip * popd +pushd /srv/CGAL/www/precompiled_libs/auxiliary/x64/ +cp CGAL-5.2-win64-auxiliary-libraries-gmp-mpfr.zip "$DEST_DIR/${PUBLIC_RELEASE_NAME}-win64-auxiliary-libraries-gmp-mpfr.zip" +popd + pushd "$DEST_DIR" printf "Compute md5sum.txt..." md5sum *.^txt > md5sum.txt diff --git a/Mesh_2/doc/Mesh_2/CGAL/lloyd_optimize_mesh_2.h b/Mesh_2/doc/Mesh_2/CGAL/lloyd_optimize_mesh_2.h index 957eaf0c380..060cb8994e8 100644 --- a/Mesh_2/doc/Mesh_2/CGAL/lloyd_optimize_mesh_2.h +++ b/Mesh_2/doc/Mesh_2/CGAL/lloyd_optimize_mesh_2.h @@ -19,14 +19,13 @@ and the Delaunay triangulation is updated. Vertices on the mesh boundaries are not moved. \tparam CDT is required to be or derive from `CGAL::Constrained_Delaunay_triangulation_2`, -with vertex base and face base of its underlying `TriangulationDataStructure_2` -respectively implementing the concepts `DelaunayMeshFaceBase_2` and `DelaunayMeshVertexBase_2`. +with vertex base and face base of its underlying `TriangulationDataStructure_2` +being models of `DelaunayMeshVertexBase_2` and `DelaunayMeshFaceBase_2`, respectively. The argument `cdt`, passed by reference, provides the initial mesh and is modified by the algorithm to represent the final optimized mesh. \tparam PointIterator must be an iterator with value type `Kernel::Point_2` - The function has several optional parameters which are named parameters (we use the Boost.Parameter library). Therefore, when calling the function, the parameters can be provided in any order diff --git a/Mesh_3/include/CGAL/Mesh_3/Slivers_exuder.h b/Mesh_3/include/CGAL/Mesh_3/Slivers_exuder.h index 29c4817021f..ee91f1d3f70 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Slivers_exuder.h +++ b/Mesh_3/include/CGAL/Mesh_3/Slivers_exuder.h @@ -36,7 +36,6 @@ #include -#include #include #include #include diff --git a/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h b/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h index 4095bb37baf..f51af8cd0b3 100644 --- a/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h +++ b/Mesh_3/include/CGAL/internal/Mesh_3/helpers.h @@ -45,7 +45,7 @@ void dump_graph_edges(std::ostream& out, const Graph& g) typedef typename boost::graph_traits::edge_descriptor edge_descriptor; out.precision(17); - for(edge_descriptor e : edges(g)) + for(edge_descriptor e : CGAL::make_range(edges(g))) { vertex_descriptor s = source(e, g); vertex_descriptor t = target(e, g); @@ -82,7 +82,7 @@ struct Angle_tester const typename Kernel::Point_3& p1 = g[v1]; const typename Kernel::Point_3& p2 = g[v2]; - return (CGAL::angle(p1, p, p2) == CGAL::ACUTE); + return (CGAL::angle(p1, p, p2) != CGAL::OBTUSE); } } }; diff --git a/Mesh_3/test/Mesh_3/CMakeLists.txt b/Mesh_3/test/Mesh_3/CMakeLists.txt index 588d5b7650c..5b7ffa7210f 100644 --- a/Mesh_3/test/Mesh_3/CMakeLists.txt +++ b/Mesh_3/test/Mesh_3/CMakeLists.txt @@ -121,6 +121,23 @@ if ( CGAL_FOUND ) target_link_libraries(${target} PUBLIC CGAL::TBB_support) endif() endforeach() + + if(BUILD_TESTING) + set_property(TEST + execution___of__test_meshing_verbose + execution___of__test_meshing_polyhedron_with_features + execution___of__test_meshing_implicit_function + execution___of__test_meshing_3D_image + execution___of__test_meshing_3D_gray_image + execution___of__test_meshing_unit_tetrahedron + execution___of__test_meshing_polyhedron + execution___of__test_meshing_polyhedral_complex + execution___of__test_mesh_capsule_var_distance_bound + execution___of__test_mesh_3_issue_1554 + execution___of__test_mesh_polyhedral_domain_with_features_deprecated + execution___of__test_mesh_cell_base_3 + PROPERTY RUN_SERIAL 1) + endif() endif() if(TARGET ITT::ITT) target_link_libraries(test_meshing_polyhedron_with_features PRIVATE ITT::ITT) diff --git a/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h b/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h index f7d33128ad2..69a1ad95ebf 100644 --- a/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h +++ b/Nef_3/include/CGAL/Nef_3/polygon_mesh_to_nef_3.h @@ -192,16 +192,18 @@ void polygon_mesh_to_nef_3(PolygonMesh& P, SNC_structure& S, FaceIndexMap fimap, typedef Halfedge_around_target_circulator Halfedge_around_vertex_const_circulator; - PMap pmap = get(CGAL::vertex_point,P); std::vector normals(num_faces(P)); + CGAL_assertion_code(std::vector num_edges(num_faces(P));) for(face_descriptor f : faces(P)){ Vertex_around_face_circulator vafc(halfedge(f,P),P), done(vafc); Vector_3 v; normal_vector_newell_3(vafc, done, pmap, v); - normals[get(fimap,f)] = - v; + std::size_t i = get(fimap,f); + normals[i] = -v; + CGAL_assertion_code(num_edges[i] = circulator_size(vafc)); } Face_graph_index_adder::reference npv = get(pmap,pv); Vertex_handle nv = S.new_vertex(); - nv->point() = get(pmap,pv); + nv->point() = npv; nv->mark() = true; - CGAL_NEF_TRACEN("v "<< get(pmap,pv)); + CGAL_NEF_TRACEN("v "<< npv); SM_decorator SM(&*nv); Halfedge_around_vertex_const_circulator pec(pv,P), pec_prev(pec), done(pec); @@ -221,7 +225,7 @@ void polygon_mesh_to_nef_3(PolygonMesh& P, SNC_structure& S, FaceIndexMap fimap, // CGAL_assertion( pe != 0 ); Point_3 pe_target_0(get(pmap,target(opposite(pe,P),P))); - Point_3 sp_point_0(CGAL::ORIGIN+(pe_target_0 - get(pmap,pv))); + Point_3 sp_point_0(CGAL::ORIGIN+(pe_target_0 - npv)); Sphere_point sp_0(sp_point_0); SVertex_handle sv_0 = SM.new_svertex(sp_0); sv_0->mark() = true; @@ -234,11 +238,11 @@ void polygon_mesh_to_nef_3(PolygonMesh& P, SNC_structure& S, FaceIndexMap fimap, bool with_border = false; do { CGAL_assertion(face(pe_prev,P) == face(opposite(pe,P),P)); - CGAL_assertion(get(pmap,target(pe_prev,P)) == get(pmap,pv)); - CGAL_assertion(get(pmap,target(pe,P)) == get(pmap,pv)); + CGAL_assertion(get(pmap,target(pe_prev,P)) == npv); + CGAL_assertion(get(pmap,target(pe,P)) == npv); Point_3 pe_target = get(pmap,target(opposite(pe,P),P)); - Point_3 sp_point = CGAL::ORIGIN+(pe_target - get(pmap,pv)); + Point_3 sp_point = CGAL::ORIGIN+(pe_target - npv); Sphere_point sp(sp_point); SVertex_handle sv = SM.new_svertex(sp); sv->mark() = true; @@ -249,11 +253,13 @@ void polygon_mesh_to_nef_3(PolygonMesh& P, SNC_structure& S, FaceIndexMap fimap, if(is_border(pe_prev,P)) with_border = true; else { - Plane ss_plane( CGAL::ORIGIN, normals[get(fimap,face(pe_prev,P))] ); + std::size_t i = get(fimap,face(pe_prev,P)); + Plane ss_plane( CGAL::ORIGIN, normals[i]); Sphere_circle ss_circle(ss_plane); - - CGAL_assertion(ss_circle.has_on(sp)); - CGAL_assertion(ss_circle.has_on(sv_prev->point())); + CGAL_assertion_code(if(num_edges[i] > 3) { + CGAL_assertion(ss_circle.has_on(sp)); + CGAL_assertion(ss_circle.has_on(sv_prev->point())); + };) SHalfedge_handle e = SM.new_shalfedge_pair(sv_prev, sv); e->circle() = ss_circle; @@ -272,20 +278,22 @@ void polygon_mesh_to_nef_3(PolygonMesh& P, SNC_structure& S, FaceIndexMap fimap, while( pec != done ); CGAL_assertion(face(pe_prev,P) == face(opposite(*pe_0,P),P)); - CGAL_assertion(get(pmap,target(pe_prev,P)) == get(pmap,pv)); - CGAL_assertion(get(pmap,target(*pe_0,P)) == get(pmap,pv)); + CGAL_assertion(get(pmap,target(pe_prev,P)) == npv); + CGAL_assertion(get(pmap,target(*pe_0,P)) == npv); SHalfedge_handle e; if(is_border(pe_prev,P)) { with_border = true; e = sv_prev->out_sedge(); } else { - Plane ss_plane( CGAL::ORIGIN, normals[get(fimap,face(pe_prev,P))] ); + std::size_t i = get(fimap,face(pe_prev,P)); + Plane ss_plane( CGAL::ORIGIN, normals[i]); Sphere_circle ss_circle(ss_plane); - CGAL_assertion(ss_plane.has_on(sv_prev->point())); - CGAL_assertion(ss_circle.has_on(sp_0)); - CGAL_assertion(ss_circle.has_on(sv_prev->point())); + CGAL_assertion_code(if(num_edges[i] > 3) { + CGAL_assertion(ss_circle.has_on(sp_0)); + CGAL_assertion(ss_circle.has_on(sv_prev->point())); + };) e = SM.new_shalfedge_pair(sv_prev, sv_0); e->circle() = ss_circle; diff --git a/Nef_3/include/CGAL/Nef_polyhedron_3.h b/Nef_3/include/CGAL/Nef_polyhedron_3.h index 3eb723d37b7..525bc7d1d0a 100644 --- a/Nef_3/include/CGAL/Nef_polyhedron_3.h +++ b/Nef_3/include/CGAL/Nef_polyhedron_3.h @@ -349,6 +349,12 @@ protected: es.build_external_structure(); } + private: + void mark_bounded_volumes() { + CGAL::Mark_bounded_volumes mbv(true); + delegate(mbv, /*compute_external*/ false, /*simplify*/ false); + } + public: /*{\Mcreation 3}*/ @@ -602,9 +608,8 @@ protected: polyhedron_3_to_nef_3 , SNC_structure>( P, snc()); build_external_structure(); + mark_bounded_volumes(); simplify(); - CGAL::Mark_bounded_volumes mbv(true); - delegate(mbv); set_snc(snc()); } @@ -616,9 +621,8 @@ protected: initialize_infibox_vertices(EMPTY); polygon_mesh_to_nef_3(const_cast(pm), snc()); build_external_structure(); + mark_bounded_volumes(); simplify(); - CGAL::Mark_bounded_volumes mbv(true); - delegate(mbv); set_snc(snc()); } @@ -637,9 +641,8 @@ protected: initialize_infibox_vertices(EMPTY); polygon_mesh_to_nef_3(const_cast(pm), snc(), fim, him); build_external_structure(); + mark_bounded_volumes(); simplify(); - CGAL::Mark_bounded_volumes mbv(true); - delegate(mbv); set_snc(snc()); } @@ -651,9 +654,8 @@ protected: initialize_infibox_vertices(EMPTY); shell_to_nef_3(N, sf, snc()); build_external_structure(); + mark_bounded_volumes(); simplify(); - CGAL::Mark_bounded_volumes mbv(true); - delegate(mbv); set_snc(snc()); } diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_LA_functors.h b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_LA_functors.h index b717a80bac4..9523d816fbb 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_LA_functors.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_LA_functors.h @@ -50,7 +50,7 @@ template struct Construct_LA_vector // Makes no sense for an unknown dimension. return typename Constructor::Dimension()(this->kernel().dimension()); } - result_type operator()(result_type const& v)const{ + result_type const& operator()(result_type const& v)const{ return v; } result_type operator()(result_type&& v)const{ @@ -137,7 +137,7 @@ template struct Compute_cartesian_coordinate { typedef typename Get_type::type RT; typedef typename R::Vector_ first_argument_type; typedef int second_argument_type; - typedef Tag_true Is_exact; + typedef Tag_true Uses_no_arithmetic; typedef decltype(std::declval()[0]) result_type; template @@ -153,7 +153,7 @@ template struct Construct_cartesian_const_iterator { typedef typename R::LA_vector S_; typedef typename R::Point_cartesian_const_iterator result_type; // same as Vector - typedef Tag_true Is_exact; + typedef Tag_true Uses_no_arithmetic; result_type operator()(argument_type const& v,Begin_tag)const{ return S_::vector_begin(v); @@ -282,7 +282,7 @@ template struct PV_dimension { typedef typename R::Vector_ argument_type; typedef int result_type; typedef typename R::LA_vector LA; - typedef Tag_true Is_exact; + typedef Tag_true Uses_no_arithmetic; template result_type operator()(T const& v) const { diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h index ed164e844da..c02efa6dcc6 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_filter_K.h @@ -42,7 +42,7 @@ template<> struct Functors_without_division > { }; // FIXME: -// - Is_exact (which should be renamed to Uses_no_arithmetic) predicates should not be filtered +// - Uses_no_arithmetic predicates should not be filtered // - Functors_without_division should be defined near/in the actual functors template < typename Base_, typename AK_, typename EK_, typename Pred_list = typeset_all > @@ -78,18 +78,24 @@ struct Cartesian_filter_K : public Base_ // TODO: only fix some types, based on some criterion? template struct Type : Get_type {}; - template::type, bool=Pred_list::template contains::value> struct Functor : - Inherit_functor {}; - template struct Functor { + template::type>::value> struct Pred_helper { typedef typename Get_functor::type AP; typedef typename Get_functor::type EP; typedef Filtered_predicate2 type; }; + // Less_cartesian_coordinate doesn't usually need filtering + // This fixes the predicate, as opposed to Inherit_functor which would leave it open (is that good?) + template struct Pred_helper : + Get_functor {}; + + template::type, bool=Pred_list::template contains::value> struct Functor : + Inherit_functor {}; + template struct Functor : + Pred_helper {}; + // TODO: // template struct Functor : // Kernel_base::template Functor {}; -// TODO: -// detect when Less_cartesian_coordinate doesn't need filtering }; } //namespace CGAL diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_static_filters.h b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_static_filters.h index 507e4144694..24b35fb4969 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_static_filters.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Cartesian_static_filters.h @@ -15,37 +15,46 @@ #include #include // bug, should be included by the next one #include +#include #include namespace CGAL { namespace SFA { // static filter adapter // Note that this would be quite a bit simpler without stateful kernels +template struct Adapter_2 { + typedef typename Get_type::type Point; + typedef typename Get_functor::type CC; + typedef typename Get_functor::type Orientation_base; + typedef typename Get_functor::type Side_of_oriented_circle_base; + struct Point_2 { + R_ const&r; CC const&c; Point const& p; + Point_2(R_ const&r_, CC const&c_, Point const&p_):r(r_),c(c_),p(p_){} + decltype(auto) x()const{return c(p,0);} + decltype(auto) y()const{return c(p,1);} + }; + struct Vector_2 {}; + struct Circle_2 {}; + struct Orientation_2 { + typedef typename Get_type::type result_type; + auto operator()(Point_2 const&A, Point_2 const&B, Point_2 const&C)const{ + Point const* t[3]={&A.p,&B.p,&C.p}; + return Orientation_base(A.r)(make_transforming_iterator(t+0),make_transforming_iterator(t+3)); + } + }; + struct Side_of_oriented_circle_2 { + typedef typename Get_type::type result_type; + auto operator()(Point_2 const&A, Point_2 const&B, Point_2 const&C, Point_2 const&D)const{ + Point const* t[3]={&A.p,&B.p,&C.p}; + return Side_of_oriented_circle_base(A.r)(make_transforming_iterator(t+0),make_transforming_iterator(t+3),D.p); + } + }; +}; template struct Orientation_of_points_2 : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Orientation_of_points_2) typedef typename Get_type::type Point; typedef typename Get_type::type result_type; - typedef typename Get_type::type FT; typedef typename Get_functor::type CC; - typedef typename Get_functor::type Orientation_base; - // TODO: Move this out for easy reuse - struct Adapter { - struct Point_2 { - R_ const&r; CC const&c; Point const& p; - Point_2(R_ const&r_, CC const&c_, Point const&p_):r(r_),c(c_),p(p_){} - // use result_of instead? - typename CC::result_type x()const{return c(p,0);} - typename CC::result_type y()const{return c(p,1);} - }; - struct Vector_2 {}; - struct Circle_2 {}; - struct Orientation_2 { - typedef typename Orientation_of_points_2::result_type result_type; - result_type operator()(Point_2 const&A, Point_2 const&B, Point_2 const&C)const{ - Point const* t[3]={&A.p,&B.p,&C.p}; - return Orientation_base(A.r)(make_transforming_iterator(t+0),make_transforming_iterator(t+3)); - } - }; - }; + typedef Adapter_2 Adapter; template result_type operator()(Iter f, Iter CGAL_assertion_code(e))const{ CC c(this->kernel()); Point const& A=*f; @@ -56,6 +65,22 @@ template struct Orientation_of_points_2 : private Store_k return typename internal::Static_filters_predicates::Orientation_2()(P(this->kernel(),c,A),P(this->kernel(),c,B),P(this->kernel(),c,C)); } }; +template struct Side_of_oriented_sphere_2 : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Side_of_oriented_sphere_2) + typedef typename Get_type::type Point; + typedef typename Get_type::type result_type; + typedef typename Get_functor::type CC; + typedef Adapter_2 Adapter; + template result_type operator()(Iter f, Iter CGAL_assertion_code(e), Point const& D)const{ + CC c(this->kernel()); + Point const& A=*f; + Point const& B=*++f; + Point const& C=*++f; + CGAL_assertion(++f==e); + typedef typename Adapter::Point_2 P; + return typename internal::Static_filters_predicates::Side_of_oriented_circle_2()(P(this->kernel(),c,A),P(this->kernel(),c,B),P(this->kernel(),c,C),P(this->kernel(),c,D)); + } +}; } template @@ -80,6 +105,9 @@ struct Cartesian_static_filters, R_, Derived_> : public R_ { // >::type type; }; + template struct Functor { + typedef SFA::Side_of_oriented_sphere_2 type; + }; }; } diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Filtered_predicate2.h b/NewKernel_d/include/CGAL/NewKernel_d/Filtered_predicate2.h index c3d2281ad96..2064af0b986 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Filtered_predicate2.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Filtered_predicate2.h @@ -39,6 +39,11 @@ namespace CGAL { // not, or we let all this up to the compiler optimizer to figure out ? // - Some caching could be done at the Point_2 level. +// Protection has a different meaning than in Filtered_predicate, it says +// whether we need to set the rounding mode: some predicates only do +// comparisons and don't need it. Probably this should be done inside this +// class, based on Uses_no_arithmetic, but I have some doubts about C2A, +// converting a long long to Interval_nt requires protection. template class Filtered_predicate2 @@ -87,7 +92,6 @@ public: catch (Uncertain_conversion_exception&) {} } CGAL_BRANCH_PROFILER_BRANCH(tmp); - Protect_FPU_rounding p(CGAL_FE_TONEAREST); return ep(c2e(std::forward(args))...); } }; diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Kernel_2_interface.h b/NewKernel_d/include/CGAL/NewKernel_d/Kernel_2_interface.h index d1515d152fc..3d6d588b142 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Kernel_2_interface.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Kernel_2_interface.h @@ -79,10 +79,11 @@ template struct Kernel_2_interface : public Base_ { Side_of_oriented_circle_2(Kernel const&k):sos(k){} result_type operator()(Point_2 const&a, Point_2 const&b, Point_2 const&c, Point_2 const&d) { //return sos(a,b,c,d); - Point_2 const* t[4]={&a,&b,&c,&d}; - return sos(make_transforming_iterator(t+0),make_transforming_iterator(t+4)); + Point_2 const* t[4]={&a,&b,&c}; + return sos(make_transforming_iterator(t+0),make_transforming_iterator(t+3), d); } }; + typedef typename Get_functor >::type Construct_point_2; Less_x_2 less_x_2_object()const{ return Less_x_2(*this); } Less_y_2 less_y_2_object()const{ return Less_y_2(*this); } Compare_x_2 compare_x_2_object()const{ return Compare_x_2(*this); } @@ -90,6 +91,7 @@ template struct Kernel_2_interface : public Base_ { Compare_distance_2 compare_distance_2_object()const{ return Compare_distance_2(*this); } Orientation_2 orientation_2_object()const{ return Orientation_2(*this); } Side_of_oriented_circle_2 side_of_oriented_circle_2_object()const{ return Side_of_oriented_circle_2(*this); } + Construct_point_2 construct_point_2_object()const{ return Construct_point_2(*this); } }; } diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Kernel_3_interface.h b/NewKernel_d/include/CGAL/NewKernel_d/Kernel_3_interface.h index 6c85a4161b9..de0258ea492 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Kernel_3_interface.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Kernel_3_interface.h @@ -76,10 +76,11 @@ template struct Kernel_3_interface : public Base_ { Side_of_oriented_sphere_3(Kernel const&k):sos(k){} result_type operator()(Point_3 const&a, Point_3 const&b, Point_3 const&c, Point_3 const&d, Point_3 const&e) { //return sos(a,b,c,d); - Point_3 const* t[5]={&a,&b,&c,&d,&e}; - return sos(make_transforming_iterator(t+0),make_transforming_iterator(t+5)); + Point_3 const* t[5]={&a,&b,&c,&d}; + return sos(make_transforming_iterator(t+0),make_transforming_iterator(t+4),e); } }; + typedef typename Get_functor >::type Construct_point_3; // I don't have the Coplanar predicates (yet) @@ -88,6 +89,7 @@ template struct Kernel_3_interface : public Base_ { Compare_distance_3 compare_distance_3_object()const{ return Compare_distance_3(*this); } Orientation_3 orientation_3_object()const{ return Orientation_3(*this); } Side_of_oriented_sphere_3 side_of_oriented_sphere_3_object()const{ return Side_of_oriented_sphere_3(*this); } + Construct_point_3 construct_point_3_object()const{ return Construct_point_3(*this); } }; } diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h b/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h index c7f3b3ebbdd..2045f8c87c3 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Lazy_cartesian.h @@ -294,7 +294,9 @@ struct Lazy_cartesian : template struct Functor { typedef typename Get_functor::type FA; typedef typename Get_functor::type FE; - typedef Filtered_predicate2 type; + // Careful if operator< for Interval_nt ever starts using arithmetic... + // Not done directly in Filtered_predicate2 because of C2A + typedef Filtered_predicate2::value> type; }; template struct Functor { typedef Lazy_construction2 type; diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Types/Hyperplane.h b/NewKernel_d/include/CGAL/NewKernel_d/Types/Hyperplane.h index c3c1de8adb9..7cf4f2189ed 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Types/Hyperplane.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Types/Hyperplane.h @@ -127,7 +127,7 @@ template struct Hyperplane_translation { CGAL_FUNCTOR_INIT_IGNORE(Hyperplane_translation) typedef typename Get_type::type Hyperplane; typedef typename Get_type::type result_type; - // TODO: Is_exact? + // TODO: Uses_no_arithmetic? result_type operator()(Hyperplane const&s)const{ return s.translation(); } diff --git a/NewKernel_d/include/CGAL/NewKernel_d/Types/Sphere.h b/NewKernel_d/include/CGAL/NewKernel_d/Types/Sphere.h index 92a5aa65c0b..19d601c6b6d 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/Types/Sphere.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/Types/Sphere.h @@ -83,7 +83,7 @@ template struct Squared_radius { CGAL_FUNCTOR_INIT_IGNORE(Squared_radius) typedef typename Get_type::type Sphere; typedef typename Get_type::type const& result_type; - // TODO: Is_exact? + // TODO: Uses_no_arithmetic? result_type operator()(Sphere const&s)const{ return s.squared_radius(); } diff --git a/NewKernel_d/include/CGAL/NewKernel_d/function_objects_cartesian.h b/NewKernel_d/include/CGAL/NewKernel_d/function_objects_cartesian.h index 3ab117131dc..605db974423 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/function_objects_cartesian.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/function_objects_cartesian.h @@ -1108,7 +1108,7 @@ template struct Less_point_cartesian_coordinate : private Store_kernel typedef typename Get_functor::type Cc; // TODO: This is_exact thing should be reengineered. // the goal is to have a way to tell: don't filter this - typedef typename CGAL::Is_exact Is_exact; + typedef typename CGAL::Uses_no_arithmetic Uses_no_arithmetic; template result_type operator()(V const&a, W const&b, I i)const{ @@ -1128,7 +1128,7 @@ template struct Compare_point_cartesian_coordinate : private Store_ker typedef typename Get_functor::type Cc; // TODO: This is_exact thing should be reengineered. // the goal is to have a way to tell: don't filter this - typedef typename CGAL::Is_exact Is_exact; + typedef typename CGAL::Uses_no_arithmetic Uses_no_arithmetic; template result_type operator()(V const&a, W const&b, I i)const{ @@ -1148,7 +1148,7 @@ template struct Compare_lexicographically : private Store_kernel { typedef typename Get_functor >::type CI; // TODO: This is_exact thing should be reengineered. // the goal is to have a way to tell: don't filter this - typedef typename CGAL::Is_exact Is_exact; + typedef typename CGAL::Uses_no_arithmetic Uses_no_arithmetic; template result_type operator()(V const&a, W const&b)const{ @@ -1176,7 +1176,7 @@ template struct Less_lexicographically : private Store_kernel { typedef R_ R; typedef typename Get_type::type result_type; typedef typename Get_functor::type CL; - typedef typename CGAL::Is_exact Is_exact; + typedef typename CGAL::Uses_no_arithmetic Uses_no_arithmetic; template result_type operator() (V const&a, W const&b) const { @@ -1194,7 +1194,7 @@ template struct Less_or_equal_lexicographically : private Store_kernel typedef R_ R; typedef typename Get_type::type result_type; typedef typename Get_functor::type CL; - typedef typename CGAL::Is_exact Is_exact; + typedef typename CGAL::Uses_no_arithmetic Uses_no_arithmetic; template result_type operator() (V const&a, W const&b) const { @@ -1214,7 +1214,7 @@ template struct Equal_points : private Store_kernel { typedef typename Get_functor >::type CI; // TODO: This is_exact thing should be reengineered. // the goal is to have a way to tell: don't filter this - typedef typename CGAL::Is_exact Is_exact; + typedef typename CGAL::Uses_no_arithmetic Uses_no_arithmetic; template result_type operator()(V const&a, W const&b)const{ diff --git a/NewKernel_d/include/CGAL/NewKernel_d/functor_properties.h b/NewKernel_d/include/CGAL/NewKernel_d/functor_properties.h index eb2f767c7a2..f8608d9fd4d 100644 --- a/NewKernel_d/include/CGAL/NewKernel_d/functor_properties.h +++ b/NewKernel_d/include/CGAL/NewKernel_d/functor_properties.h @@ -24,7 +24,7 @@ namespace CGAL { template \ struct Is_pretty : T::Is_pretty {} -CGAL_STRAWBERRY(Is_exact); +CGAL_STRAWBERRY(Uses_no_arithmetic); CGAL_STRAWBERRY(Is_fast); CGAL_STRAWBERRY(Is_stored); #undef CGAL_STRAWBERRY diff --git a/NewKernel_d/test/NewKernel_d/CMakeLists.txt b/NewKernel_d/test/NewKernel_d/CMakeLists.txt index c039a4e45b0..931c38db9a0 100644 --- a/NewKernel_d/test/NewKernel_d/CMakeLists.txt +++ b/NewKernel_d/test/NewKernel_d/CMakeLists.txt @@ -18,13 +18,20 @@ find_package(CGAL REQUIRED) find_package(Eigen3) include(CGAL_Eigen3_support) if(TARGET CGAL::Eigen3_support) - create_single_source_cgal_program("Epick_d.cpp") - target_link_libraries(Epick_d PUBLIC CGAL::Eigen3_support) + file( + GLOB cppfiles + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) + foreach(cppfile ${cppfiles}) + get_filename_component(target ${cppfile} NAME_WE) + create_single_source_cgal_program("${cppfile}") + target_link_libraries(${target} PUBLIC CGAL::Eigen3_support) + endforeach() else() message( STATUS - "NOTICE: This program requires the Eigen3 library, and will not be compiled." + "NOTICE: These programs require the Eigen3 library, and will not be compiled." ) endif() diff --git a/NewKernel_d/test/NewKernel_d/tri2.cpp b/NewKernel_d/test/NewKernel_d/tri2.cpp new file mode 100644 index 00000000000..eab4e5d2d62 --- /dev/null +++ b/NewKernel_d/test/NewKernel_d/tri2.cpp @@ -0,0 +1,77 @@ +// Benchmark on the construction of Delaunay 2D with Epick (Kernel_23) vs +// something based on NewKernel_d that uses Eigen::Vector2d as Point_2. +#if __cpp_aligned_new >= 201606L +#if 1 +#define CGAL_NEWKERNEL_D_USE_EIGEN_VECTOR 1 +#include +#include +#include + +namespace CGAL { +struct Epick_2_help1 +: Cartesian_filter_K< + Cartesian_base_d>, + Cartesian_base_d>, + Cartesian_base_d::Type, CGAL::Dimension_tag<2>> + > +{ +}; +struct Epick_2_help2 +: Cartesian_filter_K< + Epick_2_help1, + Cartesian_base_d>, + Cartesian_base_d::Type, CGAL::Dimension_tag<2>>, + Functors_without_division>::type + > +{ }; +struct Epick_2 +: Kernel_2_interface,Epick_2_help2>> +{ }; +template <> +struct Triangulation_structural_filtering_traits { + typedef Tag_true Use_structural_filtering_tag; +}; +} +typedef CGAL::Epick_2 K; +static_assert(std::is_same::value, ""); +#else +#include +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +#endif + +#include +#include +#include +#include +#include + +typedef CGAL::Delaunay_triangulation_2 DT; +typedef DT::Point Point_2; + +int main(int argc,char** argv) +{ + int n = (argc > 1) ? atoi(argv[1]) : 100000; + std::vector points; + points.reserve( n ); + + std::mt19937 gen(1234); + std::uniform_real_distribution<> dis(1.0, 2.0); + for(int i=0;i +int main(){ + std::cerr << "This program requires C++17 or later.\n"; +} +#endif diff --git a/Number_types/doc/Number_types/CGAL/Gmpfr.h b/Number_types/doc/Number_types/CGAL/Gmpfr.h index e3785df15f2..ae7ce118966 100644 --- a/Number_types/doc/Number_types/CGAL/Gmpfr.h +++ b/Number_types/doc/Number_types/CGAL/Gmpfr.h @@ -189,7 +189,7 @@ static std::float_round_style set_default_rndmode(std::float_round_style r); /*! \name Flags -\sc{Mpfr} provides some flags to know whether +\mpfr provides some flags to know whether performed operations were exact or not, or they incurred in overflow or underflow, if the exponent is out of range, or the result was `NaN` (not-a-number). One can clear the flags before a set of operations and diff --git a/Number_types/include/CGAL/NT_converter.h b/Number_types/include/CGAL/NT_converter.h index 1d7c4a8d639..ac225f1e0cb 100644 --- a/Number_types/include/CGAL/NT_converter.h +++ b/Number_types/include/CGAL/NT_converter.h @@ -61,6 +61,17 @@ struct NT_converter < NT1, double > } }; +template < class NT1 > +struct NT_converter < NT1, float > + : public CGAL::cpp98::unary_function< NT1, float > +{ + float + operator()(const NT1 &a) const + { + return static_cast(to_double(a)); + } +}; + template <> struct NT_converter < double, double > : public CGAL::cpp98::unary_function< double, double > @@ -72,6 +83,17 @@ struct NT_converter < double, double > } }; +template <> +struct NT_converter < float, float > + : public CGAL::cpp98::unary_function< float, float > +{ + const float & + operator()(const float &a) const + { + return a; + } +}; + template < class NT1, bool b > struct NT_converter < NT1, Interval_nt > : public CGAL::cpp98::unary_function< NT1, Interval_nt > diff --git a/Number_types/test/Number_types/CMakeLists.txt b/Number_types/test/Number_types/CMakeLists.txt index fdc0448365e..0ac30ad1e78 100644 --- a/Number_types/test/Number_types/CMakeLists.txt +++ b/Number_types/test/Number_types/CMakeLists.txt @@ -64,23 +64,26 @@ create_single_source_cgal_program("_test_valid_finite_float.cpp") create_single_source_cgal_program("to_interval_test.cpp") create_single_source_cgal_program("unsigned.cpp") create_single_source_cgal_program("utilities.cpp") -find_package(GMP) -if(GMP_FOUND) - create_single_source_cgal_program("CORE_Expr_ticket_4296.cpp") - find_package(MPFI) - if(MPFI_FOUND) - include(${MPFI_USE_FILE}) - endif(MPFI_FOUND) -endif(GMP_FOUND) +find_package( GMP ) +if( GMP_FOUND AND NOT CGAL_DISABLE_GMP ) + create_single_source_cgal_program( "CORE_Expr_ticket_4296.cpp" ) + find_package( MPFI ) + if( MPFI_FOUND ) + include( ${MPFI_USE_FILE} ) + endif() #MPFI_FOUND +endif() #GMP_FOUND AND NOT CGAL_DISABLE_GMP +if(NOT CGAL_DISABLE_GMP) + create_single_source_cgal_program( "Gmpfi.cpp" ) + create_single_source_cgal_program( "Gmpfr_bug.cpp" ) + create_single_source_cgal_program( "eigen.cpp" ) + find_package(Eigen3 3.2.0) #(requires 3.2.0 or greater) + include(CGAL_Eigen3_support) + if (TARGET CGAL::Eigen3_support) + target_link_libraries(eigen PUBLIC CGAL::Eigen3_support) + endif() +else()#NOT CGAL_DISABLE_GMP + message(STATUS "NOTICE: Some tests require the CGAL_Core library, and will not be compiled.") +endif()#NOT CGAL_DISABLE_GMP # all the programs below will be linked against MPFI in case it is present -create_single_source_cgal_program("Gmpfi.cpp") -create_single_source_cgal_program("Gmpfr_bug.cpp") create_single_source_cgal_program("Quotient_new.cpp") create_single_source_cgal_program("test_nt_Coercion_traits.cpp") - -create_single_source_cgal_program("eigen.cpp") -find_package(Eigen3 3.2.0) #(requires 3.2.0 or greater) -include(CGAL_Eigen3_support) -if(TARGET CGAL::Eigen3_support) - target_link_libraries(eigen PUBLIC CGAL::Eigen3_support) -endif() 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 07fb9bb3bb4..fa78978a4dd 100644 --- a/Partition_2/include/CGAL/Partition_2/Rotation_tree_2.h +++ b/Partition_2/include/CGAL/Partition_2/Rotation_tree_2.h @@ -34,7 +34,6 @@ #include #include -#include namespace CGAL { diff --git a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_Delaunay_triangulation_2.h b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_Delaunay_triangulation_2.h index 9bf894ca0d7..b95c3c7f607 100644 --- a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_Delaunay_triangulation_2.h +++ b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_Delaunay_triangulation_2.h @@ -16,12 +16,14 @@ The class `Periodic_2_Delaunay_triangulation_2` has two template parameters. The \tparam Traits is the geometric traits, it is to be instantiated by a model of the concept `Periodic_2DelaunayTriangulationTraits_2`. -The second parameter is the triangulation data structure, it has to be -instantiated by a model of the concept -`TriangulationDataStructure_2` with some additional functionality -in faces. By default, the triangulation data structure is instantiated -by -`CGAL::Triangulation_data_structure_2 < CGAL::Triangulation_vertex_base_2, CGAL::Periodic_2_triangulation_face_base_2 > >`. +\tparam Tds is the triangulation data data structure and must be a model of `TriangulationDataStructure_2` +whose vertex and face are models of `Periodic_2TriangulationVertexBase_2` and `Periodic_2TriangulationFaceBase_2`. +It defaults to: +\code +CGAL::Triangulation_data_structure_2< + CGAL::Periodic_2_triangulation_vertex_base_2, + CGAL::Periodic_2_triangulation_face_base_2 > > +\endcode \cgalHeading{Implementation} @@ -42,11 +44,8 @@ After a point location step, the nearest neighbor is found in time vertices distributed uniformly at random and any query point. \sa `CGAL::Periodic_2_triangulation_2` -\sa `CGAL::Delaunay_triangulation_2` -\sa `TriangulationDataStructure_2` -\sa `Periodic_2DelaunayTriangulationTraits_2` \sa `CGAL::Periodic_2_triangulation_hierarchy_2` - +\sa `CGAL::Delaunay_triangulation_2` */ template< typename Traits, typename Tds > class Periodic_2_Delaunay_triangulation_2 : public Periodic_2_triangulation_2 diff --git a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_2.h b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_2.h index f68062261eb..21dc5d73b09 100644 --- a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_2.h +++ b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_2.h @@ -11,15 +11,17 @@ The class `Periodic_2_triangulation_2` represents a 2-dimensional triangulation of a point set in \f$ \mathbb T_c^2\f$. \tparam Traits is the geometric traits, it -is to be instantiated by a model of the concept +has to be instantiated by a model of the concept `Periodic_2TriangulationTraits_2`. -\tparam TDS is the triangulation data structure, -it has to be instantiated by a model of the concept -`TriangulationDataStructure_2` with some additional -functionality in faces. -By default, the triangulation data structure is instantiated by -`CGAL::Triangulation_data_structure_2 < CGAL::Triangulation_vertex_base_2, CGAL::Periodic_2_triangulation_face_base_2 > >`. +\tparam Tds is the triangulation data data structure and must be a model of `TriangulationDataStructure_2` +whose vertex and face are models of `Periodic_2TriangulationVertexBase_2` and `Periodic_2TriangulationFaceBase_2`. +It defaults to: +\code +CGAL::Triangulation_data_structure_2< + CGAL::Periodic_2_triangulation_vertex_base_2, + CGAL::Periodic_2_triangulation_face_base_2 > > +\endcode \cgalHeading{Traversal of the Triangulation} @@ -67,14 +69,9 @@ their counterparts visiting all (non-virtual and virtual) features which are themselves derived from the corresponding iterators of the triangulation data structure. -\sa `Triangulation_2` -\sa `Periodic_2TriangulationTraits_2` -\sa `TriangulationDataStructure_2` -\sa `TriangulationDataStructure_2::Face` -\sa `TriangulationDataStructure_2::Vertex` -\sa `CGAL::Triangulation_data_structure_2` -\sa `CGAL::Periodic_2_triangulation_face_base_2` - +\sa `CGAL::Periodic_2_triangulation_2` +\sa `CGAL::Periodic_2_triangulation_hierarchy_2` +\sa `CGAL::Triangulation_2` */ template< typename Traits, typename Tds > class Periodic_2_triangulation_2 : public Triangulation_cw_ccw_2 diff --git a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_traits_2.h b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_traits_2.h index 726d2f5af83..e14eab6d490 100644 --- a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_traits_2.h +++ b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/CGAL/Periodic_2_triangulation_traits_2.h @@ -8,12 +8,11 @@ namespace CGAL \ingroup PkgPeriodic2Triangulation2TraitsClasses The class `Periodic_2_triangulation_traits_2` is designed as a default -traits class for the class -`Periodic_2_triangulation_2`. +traits class for the class `CGAL::Periodic_2_triangulation_2`. \tparam Traits must be a model of the `TriangulationTraits_2` concept. \tparam Periodic_2Offset_2 must be a model of the concept -`Periodic_2Offset_2` and defaults to `Periodic_2_offset_2`. +`Periodic_2Offset_2` and defaults to `CGAL::Periodic_2_offset_2`. If `Traits` is a `CGAL::Filtered_kernel` (detected when `Traits::Has_filtered_predicates` exists and is `true`), this class automatically provides filtered predicates. Similarly, statically filtered predicates diff --git a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/Periodic_2_triangulation_2.txt b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/Periodic_2_triangulation_2.txt index 0db671e9a6f..93c54224799 100644 --- a/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/Periodic_2_triangulation_2.txt +++ b/Periodic_2_triangulation_2/doc/Periodic_2_triangulation_2/Periodic_2_triangulation_2.txt @@ -256,18 +256,19 @@ The second parameter `Periodic_2Offset_2` defaults to The second template parameter of the main classes `Periodic_2_triangulation_2` and `Periodic_2_Delaunay_triangulation_2` is a -triangulation data structure class. This class can be seen as a container for +triangulation data structure class. This class must be a model of the concept +`TriangulationDataStructure_2`, which describes requirements for the class to be a container for the faces and vertices maintaining incidence and adjacency relations (see -Chapter \ref Chapter_2D_Triangulation_Data_Structure). A model of this triangulation data structure is -`Triangulation_data_structure_2`, and it is described by the -`TriangulationDataStructure_2` concept. This model is itself +Chapter \ref Chapter_2D_Triangulation_Data_Structure). In addition, the concepts +`TriangulationDataStructure_2::Vertex` and `TriangulationDataStructure_2::Face` are extended +to support periodicity: the vertex and face must be models of +`Periodic_2TriangulationVertexBase_2` and Periodic_2TriangulationFaceBase_2`. +A model of such concept is `CGAL::Triangulation_data_structure_2`. It is parameterized by a vertex base class and a face base class, which gives the possibility to customize the vertices and cells used by the triangulation data structure, and hence by the geometric triangulation using it. -To represent periodic triangulations the cell base and vertex base -classes need to meet the concepts -`Periodic_2TriangulationFaceBase_2` and -`Periodic_2TriangulationVertexBase_2`. +Basic models of the vertex and face concepts are provided: `CGAL::Periodic_2_triangulation_vertex_base_2` +and `CGAL::Periodic_2_triangulation_face_base_2`. A default value for the triangulation data structure parameter is provided in all the triangulation classes, so it does not need to be specified by diff --git a/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2.h b/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2.h index a85f7239e69..ef8a5d063f9 100644 --- a/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2.h +++ b/Periodic_2_triangulation_2/include/CGAL/Periodic_2_triangulation_2.h @@ -292,12 +292,12 @@ public: { return _gt; } - /// Returns the datastructure storing the triangulation. + /// Returns the data structure storing the triangulation. const Triangulation_data_structure & tds() const { return _tds; } - /// Returns the datastructure storing the triangulation. + /// Returns the data structure storing the triangulation. Triangulation_data_structure & tds() { return _tds; @@ -357,17 +357,17 @@ public: else return _tds.number_of_faces() / 9; } - /// Returns the number of vertices stored in the datastructure. + /// Returns the number of vertices stored in the data structure. size_type number_of_stored_vertices() const { return _tds.number_of_vertices(); } - /// Returns the number of edges stored in the datastructure. + /// Returns the number of edges stored in the data structure. size_type number_of_stored_edges() const { return _tds.number_of_edges(); } - /// Returns the number of faces stored in the datastructure. + /// Returns the number of faces stored in the data structure. size_type number_of_stored_faces() const { return _tds.number_of_faces(); @@ -1812,7 +1812,7 @@ bool Periodic_2_triangulation_2::is_valid_too_long_edges(bool verbose, { if (too_long) { - if (verbose) std::cout << "1. Too long edge not in the datastructure" << std::endl; + if (verbose) std::cout << "1. Too long edge not in the data structure" << std::endl; result = false; } result &= !too_long; @@ -1826,7 +1826,7 @@ bool Periodic_2_triangulation_2::is_valid_too_long_edges(bool verbose, too_long_edges++; if (it2 == it->second.end()) { - if (verbose) std::cout << "2. Too long edge not in the datastructure" << std::endl; + if (verbose) std::cout << "2. Too long edge not in the data structure" << std::endl; result = false; } CGAL_triangulation_assertion(result); @@ -1835,7 +1835,7 @@ bool Periodic_2_triangulation_2::is_valid_too_long_edges(bool verbose, { if (it2 != it->second.end()) { - if (verbose) std::cout << "Edge is not too long, but contained in the datastructure" << std::endl; + if (verbose) std::cout << "Edge is not too long, but contained in the data structure" << std::endl; result = false; } CGAL_triangulation_assertion(result); diff --git a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_Delaunay_triangulation_3.h b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_Delaunay_triangulation_3.h index 784f44ff1c7..6a1e4c5d911 100644 --- a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_Delaunay_triangulation_3.h +++ b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_Delaunay_triangulation_3.h @@ -9,8 +9,15 @@ Delaunay triangulation in three-dimensional periodic space. \tparam PT must be a model of the concept `Periodic_3DelaunayTriangulationTraits_3`. -\tparam TDS must be a model of the concept `TriangulationDataStructure_3`. Its default value -is `Triangulation_data_structure_3>,Triangulation_cell_base_3>>`. +\tparam TDS must be a model of the concept `TriangulationDataStructure_3` whose +vertex and cell are models of `Periodic_3TriangulationDSVertexBase_3` and `Periodic_3TriangulationDSCellBase_3`, +respectively. +It defaults to: +\code +CGAL::Triangulation_data_structure_3< + CGAL::Triangulation_vertex_base_3 >, + CGAL::Triangulation_cell_base_3 > > +\endcode */ template< typename PT, typename TDS > diff --git a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_Delaunay_triangulation_traits_3.h b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_Delaunay_triangulation_traits_3.h index 770ac8e656c..d5c6de09876 100644 --- a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_Delaunay_triangulation_traits_3.h +++ b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_Delaunay_triangulation_traits_3.h @@ -8,7 +8,7 @@ The class `Periodic_3_Delaunay_triangulation_traits_3` is designed as a default class `Periodic_3_Delaunay_triangulation_3`. \tparam Traits must be a model of the `DelaunayTriangulationTraits_3` concept. -\tparam Offset must be a model of the concept `Periodic_3Offset_3` and defaults to `Periodic_3_offset_3`. +\tparam Offset must be a model of the concept `Periodic_3Offset_3` and defaults to `CGAL::Periodic_3_offset_3`. If `Traits` is a `CGAL::Filtered_kernel` (detected when `Traits::Has_filtered_predicates` exists and is `true`), this class automatically provides filtered predicates. Similarly, statically filtered predicates diff --git a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_regular_triangulation_3.h b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_regular_triangulation_3.h index b15ac483eb2..5e8938db6c0 100644 --- a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_regular_triangulation_3.h +++ b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_regular_triangulation_3.h @@ -9,11 +9,18 @@ weighted Delaunay triangulation in three-dimensional periodic space. \tparam PT must be a model of the concept `Periodic_3RegularTriangulationTraits_3`. -\tparam TDS must be a model of the concept `TriangulationDataStructure_3`. -Its default value is -`Triangulation_data_structure_3 >, - Regular_triangulation_cell_base_3>>`. +\tparam TDS must be a model of the concept `TriangulationDataStructure_3` whose +vertex and cell are models of `Periodic_3RegularTriangulationDSVertexBase_3` +and `Periodic_3RegularTriangulationDSCellBase_3`, respectively. +Its default value is: +\code +CGAL::Triangulation_data_structure_3< + CGAL::Regular_triangulation_vertex_base_3 >, + CGAL::Regular_triangulation_cell_base_3 > > +\endcode +\sa `CGAL::Periodic_3_triangulation_3` +\sa `CGAL::Periodic_3_Delaunay_triangulation_3` */ template< typename PT, typename TDS > class Periodic_3_regular_triangulation_3 : diff --git a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_regular_triangulation_traits_3.h b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_regular_triangulation_traits_3.h index 8a4ec39a0cf..acfe43f7c32 100644 --- a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_regular_triangulation_traits_3.h +++ b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_regular_triangulation_traits_3.h @@ -8,7 +8,7 @@ The class `Periodic_3_regular_triangulation_traits_3` is designed as a default t class `Periodic_3_regular_triangulation_3`. \tparam Traits must be a model of the `RegularTriangulationTraits_3` concept. -\tparam Offset must be a model of the concept `Periodic_3Offset_3` and defaults to `Periodic_3_offset_3`. +\tparam Offset must be a model of the concept `Periodic_3Offset_3` and defaults to `CGAL::Periodic_3_offset_3`. If `Traits` is a `CGAL::Filtered_kernel` (detected when `Traits::Has_filtered_predicates` exists and is `true`), this class automatically provides filtered predicates. diff --git a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_triangulation_3.h b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_triangulation_3.h index 3bb1bb28506..10569a5784c 100644 --- a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_triangulation_3.h +++ b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/CGAL/Periodic_3_triangulation_3.h @@ -9,13 +9,17 @@ triangulation of a point set in \f$ \mathbb T_c^3\f$. \tparam Traits must be a model of the concept `Periodic_3TriangulationTraits_3`. -\tparam TDS must be a model of the concept `TriangulationDataStructure_3` -with some additional functionality in cells and vertices. -Its default value is -`Triangulation_data_structure_3>,Triangulation_cell_base_3>>`. +\tparam TDS must be a model of the concept `TriangulationDataStructure_3` with +vertex and cell are models of `Periodic_3TriangulationDSVertexBase_3` and `Periodic_3TriangulationDSCellBase_3`, +Its default value is: +\code +CGAL::Triangulation_data_structure_3< + CGAL::Triangulation_vertex_base_3 >, + CGAL::Triangulation_cell_base_3 > > +\endcode -\sa `Periodic_3_Delaunay_triangulation_3` -\sa `Periodic_3_regular_triangulation_3` +\sa `CGAL::Periodic_3_Delaunay_triangulation_3` +\sa `CGAL::Periodic_3_regular_triangulation_3` */ template< typename Traits, typename TDS > class Periodic_3_triangulation_3 { diff --git a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Concepts/Periodic_3RegularTriangulationDSCellBase_3.h b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Concepts/Periodic_3RegularTriangulationDSCellBase_3.h index 98b07f6d6b7..59afc1e24c3 100644 --- a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Concepts/Periodic_3RegularTriangulationDSCellBase_3.h +++ b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Concepts/Periodic_3RegularTriangulationDSCellBase_3.h @@ -7,9 +7,9 @@ \cgalRefines `Periodic_3TriangulationDSCellBase_3` \cgalHasModel `CGAL::Regular_triangulation_cell_base_3 >` + Periodic_3_triangulation_ds_cell_base_3< > >` \cgalHasModel `CGAL::Regular_triangulation_cell_base_with_weighted_circumcenter_3 >` + Periodic_3_triangulation_ds_cell_base_3< > >` The template parameter `Periodic_3RegularTriangulationTraits_3` is expected to be the same as the traits class used in `CGAL::Periodic_3_regular_triangulation_3`. diff --git a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Concepts/Periodic_3RegularTriangulationDSVertexBase_3.h b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Concepts/Periodic_3RegularTriangulationDSVertexBase_3.h index 1d2a7bec41c..43ff786e30a 100644 --- a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Concepts/Periodic_3RegularTriangulationDSVertexBase_3.h +++ b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Concepts/Periodic_3RegularTriangulationDSVertexBase_3.h @@ -7,7 +7,7 @@ \cgalRefines `Periodic_3TriangulationDSVertexBase_3` \cgalHasModel `CGAL::Regular_triangulation_vertex_base_3 >` + Periodic_3_triangulation_ds_vertex_base_3< > >` The template parameter `Periodic_3RegularTriangulationTraits_3` is expected to be the same as the traits class used in `CGAL::Periodic_3_regular_triangulation_3`. diff --git a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Periodic_3_triangulation_3.txt b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Periodic_3_triangulation_3.txt index a1998b9165b..92eb9015cef 100644 --- a/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Periodic_3_triangulation_3.txt +++ b/Periodic_3_triangulation_3/doc/Periodic_3_triangulation_3/Periodic_3_triangulation_3.txt @@ -219,17 +219,17 @@ The first template parameter of the triangulation class `Periodic_3_triangulation_3` is the geometric traits class, described by the concept `Periodic_3TriangulationTraits_3`. It is different to the -TriangulationTraits_3 (see +`TriangulationTraits_3` (see chapter \ref Triangulation3secTraits "3D Triangulations") in that it implements all objects, predicates and constructions using offsets. -The class `Periodic_3_triangulation_traits_3` +The class `CGAL::Periodic_3_triangulation_traits_3` provides the required functionality. It expects two template parameters: a model of the concept `TriangulationTraits_3` and a model of the concept `Periodic_3Offset_3`. The second parameter `Periodic_3Offset_3` defaults to -`Periodic_3_offset_3`. +`CGAL::Periodic_3_offset_3`. \subsubsection P3Triangulation3secTraitsP3DT3 Traits for Periodic Delaunay Triangulations @@ -237,7 +237,7 @@ The first template parameter of the Delaunay triangulation class `Periodic_3_Delaunay_triangulation_3` is the geometric traits class, described by the concept `Periodic_3DelaunayTriangulationTraits_3`. It is different to the -DelaunayTriangulationTraits_3 (see +`DelaunayTriangulationTraits_3` (see chapter \ref Triangulation3secTraits "3D Triangulations") in that it implements all objects, predicates and constructions using offsets. @@ -246,9 +246,7 @@ provides the required functionality. It expects two template parameters: a model of the concept `DelaunayTriangulationTraits_3` and a model of the concept `Periodic_3Offset_3`. -The second parameter `Periodic_3Offset_3` defaults to -`Periodic_3_offset_3`. - +The second parameter `Periodic_3Offset_3` defaults to `CGAL::Periodic_3_offset_3`. \subsubsection P3Triangulation3secTraitsP3regularT3 Traits for Periodic Regular Triangulations @@ -290,18 +288,14 @@ triangles, and tetrahedra are used. \subsection P3Triangulation3sectds The Triangulation Data Structure Parameter The second template parameter of the periodic triangulation classes is a -triangulation data structure class. This class can be seen as a container for -the cells and vertices maintaining incidence and adjacency relations (see -Chapter \ref chapterTDS3 "3D Triangulation Data Structure"). A model of this triangulation data structure is -`Triangulation_data_structure_3`, and it is described by the -`TriangulationDataStructure_3` concept. This model is itself -parameterized by a vertex base class and a cell base class, which gives the -possibility to customize the vertices and cells used by the triangulation data -structure, and hence by the geometric triangulation using it. -To represent periodic triangulations the cell base and vertex base -classes need to meet the concepts -`Periodic_3TriangulationDSCellBase_3` and -`Periodic_3TriangulationDSVertexBase_3`. +triangulation data structure class. +This parameter must meet the requirements described in the concept `TriangulationDataStructure_3`, +for which \cgal offers the model `CGAL::Triangulation_data_structure_3`. +To represent periodic triangulations, +the face and vertex of the triangulation data structure must be also be models of extended concepts. +The model `CGAL::Triangulation_data_structure_3` is parameterized by a vertex +base class and a face base class, which gives the possibility to customize the vertices and +faces used by the triangulation data structure. A default value for the triangulation data structure parameter is provided in all the triangulation classes, so it does not need to be specified by diff --git a/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_2.h b/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_2.h index 514460645ab..aa67d8eee10 100644 --- a/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_2.h +++ b/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_2.h @@ -21,10 +21,12 @@ The class expects two template parameters. and faces, following the concepts `Periodic_4HyperbolicTriangulationVertexBase_2` and `Periodic_4HyperbolicTriangulationFaceBase_2`, respectively. The default value for this parameter is - `Triangulation_data_structure_2< Periodic_4_hyperbolic_triangulation_vertex_base_2, Periodic_4_hyperbolic_triangulation_face_base_2 >` - + \code + CGAL::Triangulation_data_structure_2< + CGAL::Periodic_4_hyperbolic_triangulation_vertex_base_2, + CGAL::Periodic_4_hyperbolic_triangulation_face_base_2 > + \endcode */ - template < class GT, class TDS > class Periodic_4_hyperbolic_Delaunay_triangulation_2: public Periodic_4_hyperbolic_triangulation_2 { diff --git a/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/CGAL/Periodic_4_hyperbolic_triangulation_2.h b/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/CGAL/Periodic_4_hyperbolic_triangulation_2.h index 6c71eb1993f..08ea200278e 100644 --- a/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/CGAL/Periodic_4_hyperbolic_triangulation_2.h +++ b/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/CGAL/Periodic_4_hyperbolic_triangulation_2.h @@ -21,11 +21,12 @@ The class expects two template parameters. and faces, following the concepts `Periodic_4HyperbolicTriangulationVertexBase_2` and `Periodic_4HyperbolicTriangulationFaceBase_2`, respectively. The default value for this parameter is - `Triangulation_data_structure_2< Periodic_4_hyperbolic_triangulation_vertex_base_2, Periodic_4_hyperbolic_triangulation_face_base_2 >` - + \code + CGAL::Triangulation_data_structure_2< + CGAL::Periodic_4_hyperbolic_triangulation_vertex_base_2, + CGAL::Periodic_4_hyperbolic_triangulation_face_base_2 > + \endcode */ - - template < class GT, class TDS > class Periodic_4_hyperbolic_triangulation_2 { diff --git a/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/Periodic_4_hyperbolic_triangulation_2.txt b/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/Periodic_4_hyperbolic_triangulation_2.txt index 586d94b3143..f5bdc8e3990 100644 --- a/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/Periodic_4_hyperbolic_triangulation_2.txt +++ b/Periodic_4_hyperbolic_triangulation_2/doc/Periodic_4_hyperbolic_triangulation_2/Periodic_4_hyperbolic_triangulation_2.txt @@ -289,12 +289,13 @@ The triangulation data structure is a container for the faces and vertices and m incidence and adjacency relations. This parameter must meet the requirements described in the concept `TriangulationDataStructure_2`, for which \cgal offers the model `Triangulation_data_structure_2`. -This model is itself parameterized by a vertex -base class and a face base class, which gives the possibility to customize the vertices and -faces used by the triangulation data structure. To represent periodic hyperbolic triangulations, -the face base and vertex base classes must be models of the concepts +To represent periodic hyperbolic triangulations, +the face and vertex of the triangulation data structure must be models of the concepts `Periodic_4HyperbolicTriangulationFaceBase_2` and `Periodic_4HyperbolicTriangulationVertexBase_2`, respectively. +The model `CGAL::Triangulation_data_structure_2` is parameterized by a vertex +base class and a face base class, which gives the possibility to customize the vertices and +faces used by the triangulation data structure. The default value for the triangulation data structure parameter is `Triangulation_data_structure_2< Periodic_4_hyperbolic_triangulation_vertex_base_2, Periodic_4_hyperbolic_triangulation_face_base_2 >`, diff --git a/Periodic_4_hyperbolic_triangulation_2/include/CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_2.h b/Periodic_4_hyperbolic_triangulation_2/include/CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_2.h index cd4166330cd..0c74a7a8be4 100644 --- a/Periodic_4_hyperbolic_triangulation_2/include/CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_2.h +++ b/Periodic_4_hyperbolic_triangulation_2/include/CGAL/Periodic_4_hyperbolic_Delaunay_triangulation_2.h @@ -27,8 +27,6 @@ #include #include -#include - #include #include #include diff --git a/Point_set_processing_3/include/CGAL/compute_average_spacing.h b/Point_set_processing_3/include/CGAL/compute_average_spacing.h index d9fdd38f040..0f98e72c863 100644 --- a/Point_set_processing_3/include/CGAL/compute_average_spacing.h +++ b/Point_set_processing_3/include/CGAL/compute_average_spacing.h @@ -81,7 +81,7 @@ compute_average_spacing(const typename NeighborQuery::Kernel::Point_3& query, // boost::make_function_output_iterator ([&](const Point& p) { - sum_distances += std::sqrt(CGAL::squared_distance (query,p)); + sum_distances += CGAL::approximate_sqrt(CGAL::squared_distance (query,p)); ++ i; })); diff --git a/Point_set_processing_3/include/CGAL/edge_aware_upsample_point_set.h b/Point_set_processing_3/include/CGAL/edge_aware_upsample_point_set.h index 260bc291747..153159fffd8 100644 --- a/Point_set_processing_3/include/CGAL/edge_aware_upsample_point_set.h +++ b/Point_set_processing_3/include/CGAL/edge_aware_upsample_point_set.h @@ -212,8 +212,8 @@ update_new_point( for (unsigned int j = 0; j < candidate_num; j++) { - FT psi = std::exp(-std::pow(1 - normal_cadidate[j] * t.normal, 2) - / sharpness_bandwidth); + FT psi = std::exp(-std::pow(FT(1) - normal_cadidate[j] * t.normal, FT(2)) + / sharpness_bandwidth); FT project_diff_t_v = (t.pt - new_v.pt) * t.normal; FT weight = psi * theta; @@ -433,7 +433,8 @@ edge_aware_upsample_point_set( FT(neighbor_radius)); // - FT cos_sigma = static_cast(std::cos(CGAL::to_double(sharpness_angle) / 180.0 * CGAL_PI)); + FT cos_sigma = static_cast(std::cos(FT(CGAL::to_double(sharpness_angle)) + / FT(180) * FT(CGAL_PI))); FT sharpness_bandwidth = std::pow((CGAL::max)((FT)1e-8, (FT)1.0 - cos_sigma), 2); FT sum_density = 0.0; diff --git a/Point_set_processing_3/include/CGAL/hierarchy_simplify_point_set.h b/Point_set_processing_3/include/CGAL/hierarchy_simplify_point_set.h index 1ddf0068651..5a115be66c8 100644 --- a/Point_set_processing_3/include/CGAL/hierarchy_simplify_point_set.h +++ b/Point_set_processing_3/include/CGAL/hierarchy_simplify_point_set.h @@ -109,7 +109,7 @@ namespace CGAL { \ingroup PkgPointSetProcessing3Algorithms Recursively split the point set in smaller clusters until the - clusters have less than `size` elements and until their variation + clusters have fewer than `size` elements and until their variation factor is below `var_max`. This method modifies the order of input points so as to pack all remaining points first, diff --git a/Point_set_processing_3/test/Point_set_processing_3/CMakeLists.txt b/Point_set_processing_3/test/Point_set_processing_3/CMakeLists.txt index 913abb26a8a..ac02dcc3ffd 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/CMakeLists.txt +++ b/Point_set_processing_3/test/Point_set_processing_3/CMakeLists.txt @@ -10,7 +10,7 @@ find_package(CGAL REQUIRED) if (MSVC) if ( CMAKE_SIZEOF_VOID_P EQUAL 4 ) # Allow Windows 32bit applications to use up to 3GB of RAM - SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE") endif() # Prints new compilation options message( STATUS "USING DEBUG CXXFLAGS = '${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG}'" ) diff --git a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_mesh_cell_criteria_3.h b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_mesh_cell_criteria_3.h index 74d507927ea..4c78d772ce5 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_mesh_cell_criteria_3.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_mesh_cell_criteria_3.h @@ -27,15 +27,16 @@ namespace Poisson { template class Constant_sizing_field { - double sq_radius_bound; + typedef typename Tr::FT FT; + FT sq_radius_bound; public: - double cell_radius_bound() const { return CGAL::sqrt(sq_radius_bound); } + FT cell_radius_bound() const { return CGAL::approximate_sqrt(sq_radius_bound); } - Constant_sizing_field(double sq_radius_bound = 0.) + Constant_sizing_field(FT sq_radius_bound = 0.) : sq_radius_bound(sq_radius_bound) {} template - double operator()(const Point&) const { return sq_radius_bound; } + FT operator()(const Point&) const { return sq_radius_bound; } }; // end class Constant_sizing_field } // end namespace Poisson diff --git a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h index 80e3a9d10ff..7fb5c3e68f3 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/Poisson_reconstruction_function.h @@ -110,18 +110,19 @@ struct Poisson_visitor { // The wrapper stores only pointers to the two functors. template struct Special_wrapper_of_two_functions_keep_pointers { + typedef typename F2::FT FT; F1 *f1; F2 *f2; Special_wrapper_of_two_functions_keep_pointers(F1* f1, F2* f2) : f1(f1), f2(f2) {} template - double operator()(const X& x) const { + FT operator()(const X& x) const { return (std::max)((*f1)(x), CGAL::square((*f2)(x))); } template - double operator()(const X& x) { + FT operator()(const X& x) { return (std::max)((*f1)(x), CGAL::square((*f2)(x))); } }; // end struct Special_wrapper_of_two_functions_keep_pointers @@ -211,7 +212,7 @@ private: { private: std::atomic m_state; - std::array m_bary; + std::array m_bary; public: Cached_bary_coord() : m_state (UNINITIALIZED) { } @@ -242,8 +243,8 @@ private: void set_initialized() { m_state = INITIALIZED; } - const double& operator[] (const std::size_t& idx) const { return m_bary[idx]; } - double& operator[] (const std::size_t& idx) { return m_bary[idx]; } + const FT& operator[] (const std::size_t& idx) const { return m_bary[idx]; } + FT& operator[] (const std::size_t& idx) { return m_bary[idx]; } }; // Wrapper for thread safety of maintained cell hint for fast diff --git a/Poisson_surface_reconstruction_3/include/CGAL/poisson_surface_reconstruction.h b/Poisson_surface_reconstruction_3/include/CGAL/poisson_surface_reconstruction.h index dddb6759fe7..3a79d458803 100644 --- a/Poisson_surface_reconstruction_3/include/CGAL/poisson_surface_reconstruction.h +++ b/Poisson_surface_reconstruction_3/include/CGAL/poisson_surface_reconstruction.h @@ -94,9 +94,10 @@ namespace CGAL { typedef typename boost::property_traits::value_type Point; typedef typename Kernel_traits::Kernel Kernel; typedef typename Kernel::Sphere_3 Sphere; + typedef typename Kernel::FT FT; typedef CGAL::Poisson_reconstruction_function Poisson_reconstruction_function; - typedef CGAL::Surface_mesh_default_triangulation_3 STr; + typedef typename CGAL::Surface_mesher::Surface_mesh_default_triangulation_3_generator::Type STr; typedef CGAL::Surface_mesh_complex_2_in_triangulation_3 C2t3; typedef CGAL::Implicit_surface_3 Surface_3; @@ -106,10 +107,10 @@ namespace CGAL { Point inner_point = function.get_inner_point(); Sphere bsphere = function.bounding_sphere(); - double radius = std::sqrt(bsphere.squared_radius()); + FT radius = CGAL::approximate_sqrt(bsphere.squared_radius()); - double sm_sphere_radius = 5.0 * radius; - double sm_dichotomy_error = sm_distance * spacing / 1000.0; + FT sm_sphere_radius = 5.0 * radius; + FT sm_dichotomy_error = sm_distance * spacing / 1000.0; Surface_3 surface(function, Sphere (inner_point, sm_sphere_radius * sm_sphere_radius), diff --git a/Polygon/include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h b/Polygon/include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h index 431fa2effa0..8338ce335a2 100644 --- a/Polygon/include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h +++ b/Polygon/include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h @@ -519,7 +519,7 @@ Orientation orientation_2(ForwardIterator first, if (next == last) next = first; - // if the range [first,last) contains less than three points, then some + // if the range [first,last) contains fewer than three points, then some // of the points (prev,i,next) will coincide // return the orientation of the triple (prev,i,next) diff --git a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt index 6c19cbdbb15..699614c41d0 100644 --- a/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt +++ b/Polygon_mesh_processing/doc/Polygon_mesh_processing/examples.txt @@ -22,6 +22,7 @@ \example Poisson_surface_reconstruction_3/poisson_reconstruction_example.cpp \example Polygon_mesh_processing/corefinement_difference_remeshed.cpp \example Polygon_mesh_processing/corefinement_mesh_union.cpp +\example Polygon_mesh_processing/corefinement_OM_union.cpp \example Polygon_mesh_processing/corefinement_mesh_union_and_intersection.cpp \example Polygon_mesh_processing/corefinement_consecutive_bool_op.cpp \example Polygon_mesh_processing/detect_features_example.cpp diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt index e34c91b8892..f979cf8cad3 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/CMakeLists.txt @@ -97,6 +97,10 @@ if(OpenMesh_FOUND) target_link_libraries(compute_normals_example_OM PRIVATE ${OPENMESH_LIBRARIES}) + create_single_source_cgal_program("corefinement_OM_union.cpp") + target_link_libraries(corefinement_OM_union + PRIVATE ${OPENMESH_LIBRARIES}) + if(TARGET CGAL::Eigen3_support) create_single_source_cgal_program("hole_filling_example_OM.cpp") target_link_libraries(hole_filling_example_OM PRIVATE CGAL::Eigen3_support diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_OM_union.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_OM_union.cpp new file mode 100644 index 00000000000..fd858fd1341 --- /dev/null +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_OM_union.cpp @@ -0,0 +1,102 @@ +#include +#include +#include +#include + +#include + +#include + +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; // default kernel for OpenMesh point type +typedef CGAL::Exact_predicates_exact_constructions_kernel EK; // alternatice kernel we want to use +typedef OpenMesh::PolyMesh_ArrayKernelT< > Mesh; + + +typedef boost::property_map >::type Exact_point_map; + +struct Exact_vertex_point_map +{ + // typedef for the property map + typedef boost::property_traits::value_type value_type; + typedef boost::property_traits::reference reference; + typedef boost::property_traits::category category; + typedef boost::property_traits::key_type key_type; + + // exterior references + Exact_point_map exact_point_map; + Mesh* tm_ptr; + + // Converters + CGAL::Cartesian_converter to_exact; + CGAL::Cartesian_converter to_input; + + Exact_vertex_point_map() + : tm_ptr(nullptr) + {} + + Exact_vertex_point_map(const Exact_point_map& ep, Mesh& tm) + : exact_point_map(ep) + , tm_ptr(&tm) + { + for (key_type v : vertices(tm)) + put(exact_point_map, v, to_exact(get(boost::vertex_point, tm, v))); + } + + friend + reference get(const Exact_vertex_point_map& map, key_type k) + { + CGAL_precondition(map.tm_ptr!=nullptr); + return get(map.exact_point_map, k); + } + + friend + void put(const Exact_vertex_point_map& map, key_type k, const EK::Point_3& p) + { + CGAL_precondition(map.tm_ptr!=nullptr); + put(map.exact_point_map, k, p); + // create the input point from the exact one + put(boost::vertex_point, *map.tm_ptr, k, map.to_input(p)); + } +}; + +namespace PMP = CGAL::Polygon_mesh_processing; + +int main(int argc, char* argv[]) +{ + const char* filename1 = (argc > 1) ? argv[1] : "data/blobby.off"; + const char* filename2 = (argc > 2) ? argv[2] : "data/eight.off"; + + Mesh mesh1, mesh2; + + OpenMesh::IO::read_mesh(mesh1, filename1); + OpenMesh::IO::read_mesh(mesh2, filename2); + + Mesh out; + + // Create exact map properties + Exact_point_map pm_1 = get(CGAL::dynamic_vertex_property_t(), mesh1); + Exact_point_map pm_2 = get(CGAL::dynamic_vertex_property_t(), mesh2); + Exact_point_map pm_out = get(CGAL::dynamic_vertex_property_t(), out); + + // Create exact vertex point map that will provide the point to another kernel and fill the default map + Exact_vertex_point_map vpm_1(pm_1, mesh1); + Exact_vertex_point_map vpm_2(pm_2, mesh2); + Exact_vertex_point_map vpm_out(pm_out, out); + + bool valid_union = PMP::corefine_and_compute_union(mesh1, mesh2, out, + CGAL::parameters::vertex_point_map(vpm_1), + CGAL::parameters::vertex_point_map(vpm_2), + CGAL::parameters::vertex_point_map(vpm_out)); + + if (valid_union) + { + std::cout << "Union was successfully computed\n"; + OpenMesh::IO::write_mesh(out, "union.off"); + return 0; + } + std::cout << "Union could not be computed\n"; + return 1; +} diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_consecutive_bool_op.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_consecutive_bool_op.cpp index ebd86cda4ac..5c70a466b34 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_consecutive_bool_op.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_consecutive_bool_op.cpp @@ -8,14 +8,11 @@ #include #include -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Exact_predicates_exact_constructions_kernel EK; - -typedef CGAL::Surface_mesh Mesh; -typedef boost::graph_traits::vertex_descriptor vertex_descriptor; - -typedef Mesh::Property_map Exact_point_map; -typedef Mesh::Property_map Exact_point_computed; +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Exact_predicates_exact_constructions_kernel EK; +typedef CGAL::Surface_mesh Mesh; +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef Mesh::Property_map Exact_point_map; namespace PMP = CGAL::Polygon_mesh_processing; namespace params = PMP::parameters; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h index 4b43e6f3bbf..5fd919df74d 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h @@ -41,6 +41,7 @@ #include #include #include +#include namespace CGAL{ namespace Polygon_mesh_processing { @@ -48,24 +49,6 @@ namespace Polygon_mesh_processing { namespace internal { -template -int -inter_pt_index(int i, int j, - const Plane_3& plane, - std::vector& points, - std::map, int>& id_map) -{ - std::pair, int>::iterator, bool> res = - id_map.insert(std::make_pair(make_sorted_pair(i,j), - static_cast (points.size()))); - if(res.second) - points.push_back( - typename Geom_traits::Construct_plane_line_intersection_point_3() - (plane, points[i], points[j])); - - return res.first->second; -} - template @@ -106,19 +89,42 @@ clip_to_bbox(const Plane_3& plane, }}; // description of faces of the bbox - std::array face_indices = - {{ 0, 1, 2, 3, - 2, 1, 5, 6, - 3, 2, 6, 7, - 1, 0, 4, 5, - 4, 0, 3, 7, - 6, 5, 4, 7 }}; + constexpr std::array face_indices + { { 0, 1, 2, 3, + 2, 1, 5, 6, + 3, 2, 6, 7, + 1, 0, 4, 5, + 4, 0, 3, 7, + 6, 5, 4, 7 } }; + + constexpr std::array edge_indices + { { 0, 1, 2, 3, + 1, 4, 5, 6, + 2, 6, 7, 8, + 0, 9, 10, 4, + 9, 3, 8, 11, + 5, 10, 11, 7 } }; + + std::array edge_ipt_id; + edge_ipt_id.fill(-1); + + auto inter_pt_index = + [&plane, &corners, &edge_ipt_id](int i, int j, int edge_id) + { + if (edge_ipt_id[edge_id]==-1) + { + edge_ipt_id[edge_id] = static_cast (corners.size()); + corners.push_back(typename Geom_traits::Construct_plane_line_intersection_point_3() + (plane, corners[i], corners[j])); + } + + return edge_ipt_id[edge_id]; + }; - std::map, int> id_map; std::vector< std::vector > output_faces(6); bool all_in = true; bool all_out = true; - std::set in_point_ids; // to collect the set of points in the clipped bbox + std::bitset<14> in_point_bits; // to collect the set of points in the clipped bbox // for each face of the bbox, we look for intersection of the plane with its edges for(int i=0; i<6; ++i) @@ -127,6 +133,7 @@ clip_to_bbox(const Plane_3& plane, { int current_id = face_indices[4*i + k]; int next_id = face_indices[4*i + (k+1)%4]; + int edge_id = edge_indices[4 * i + k]; switch(orientations[ current_id ]) { @@ -135,13 +142,13 @@ clip_to_bbox(const Plane_3& plane, all_out=false; // point on or on the negative side output_faces[i].push_back(current_id); - in_point_ids.insert(output_faces[i].back()); + in_point_bits.set(output_faces[i].back()); // check for intersection of the edge if(orientations[ next_id ] == ON_POSITIVE_SIDE) { output_faces[i].push_back( - inter_pt_index(current_id, next_id, plane, corners, id_map)); - in_point_ids.insert(output_faces[i].back()); + inter_pt_index(current_id, next_id, edge_id)); + in_point_bits.set(output_faces[i].back()); } break; } @@ -152,15 +159,15 @@ clip_to_bbox(const Plane_3& plane, if(orientations[ next_id ] == ON_NEGATIVE_SIDE) { output_faces[i].push_back( - inter_pt_index(current_id, next_id, plane, corners, id_map)); - in_point_ids.insert(output_faces[i].back()); + inter_pt_index(current_id, next_id, edge_id)); + in_point_bits.set(output_faces[i].back()); } break; } case ON_ORIENTED_BOUNDARY: { output_faces[i].push_back(current_id); - in_point_ids.insert(output_faces[i].back()); + in_point_bits.set(output_faces[i].back()); } } } @@ -182,11 +189,14 @@ clip_to_bbox(const Plane_3& plane, typedef typename graph_traits::face_descriptor face_descriptor; std::map out_vertices; - for(int i : in_point_ids) + for(int i=0; i<14;++i) { - vertex_descriptor v = add_vertex(tm_out); - out_vertices.insert(std::make_pair(i, v)); - put(vpm_out, v, corners[i]); + if (in_point_bits.test(i)) + { + vertex_descriptor v = add_vertex(tm_out); + out_vertices.insert(std::make_pair(i, v)); + put(vpm_out, v, corners[i]); + } } std::map< std::pair, halfedge_descriptor> hedge_map; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h index c00c8771b86..07268ec93ed 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h @@ -1371,7 +1371,17 @@ public: CGAL::Bounded_side in_tm2 = is_tm2_inside_out ? ON_UNBOUNDED_SIDE : ON_BOUNDED_SIDE; - Side_of_triangle_mesh inside_tm2(tm2, vpm2); + typedef typename Nodes_vector::Exact_kernel Exact_kernel; + typedef Side_of_helper VPM_helper; + typedef typename VPM_helper::VPM SOTM_vpm2; + typedef typename VPM_helper::Tree_type Tree_type; + + Tree_type tree; + VPM_helper::build_tree(tm2, tree, vertex_to_node_id2, fids2, vpm2, nodes); + Side_of_triangle_mesh inside_tm2(tree); for(face_descriptor f : faces(tm1)) { @@ -1382,16 +1392,20 @@ public: patch_status_not_set_tm1.reset( patch_id ); halfedge_descriptor h = halfedge(f, tm1); Node_id index_p1 = get_node_id(target(h, tm1), vertex_to_node_id1); + std::array fnids = { index_p1, index_p1, index_p1 }; if (index_p1 != NID) { h=next(h, tm1); index_p1 = get_node_id(target(h, tm1), vertex_to_node_id1); + fnids[1]=index_p1; if (index_p1 != NID) { h=next(h, tm1); index_p1 = get_node_id(target(h, tm1), vertex_to_node_id1); + fnids[2]=index_p1; } } + if (index_p1 != NID) { if (coplanar_patches_of_tm1.test(patch_id)) @@ -1401,12 +1415,13 @@ public: } else { - // triangle which is tangent at its 3 vertices - // \todo improve this part which is not robust with a kernel - // with inexact constructions. - Bounded_side position = inside_tm2(centroid(get(vpm1, source(h, tm1)), - get(vpm1, target(h, tm1)), - get(vpm1, target(next(h, tm1), tm1)) )); + typename Exact_kernel::Point_3 e_centroid = + centroid(nodes.exact_node(fnids[0]), + nodes.exact_node(fnids[1]), + nodes.exact_node(fnids[2])); + + Bounded_side position = inside_tm2(e_centroid); + CGAL_assertion( position != ON_BOUNDARY); if ( position == in_tm2 ) is_patch_inside_tm2.set(patch_id); @@ -1414,9 +1429,7 @@ public: } else { - // TODO: tm2 might have been modified and an inexact vpm will - // provide a non-robust result. - Bounded_side position = inside_tm2( get(vpm1, target(h, tm1))); + Bounded_side position = inside_tm2( nodes.to_exact(get(vpm1, target(h, tm1)))); CGAL_assertion( position != ON_BOUNDARY); if ( position == in_tm2 ) is_patch_inside_tm2.set(patch_id); @@ -1433,7 +1446,18 @@ public: CGAL::Bounded_side in_tm1 = is_tm1_inside_out ? ON_UNBOUNDED_SIDE : ON_BOUNDED_SIDE; - Side_of_triangle_mesh inside_tm1(tm1, vpm1); + typedef typename Nodes_vector::Exact_kernel Exact_kernel; + typedef Side_of_helper VPM_helper; + typedef typename VPM_helper::VPM SOTM_vpm1; + typedef typename VPM_helper::Tree_type Tree_type; + + Tree_type tree; + VPM_helper::build_tree(tm1, tree, vertex_to_node_id1, fids1, vpm1, nodes); + Side_of_triangle_mesh inside_tm1(tree); + for(face_descriptor f : faces(tm2)) { const std::size_t f_id = get(fids2, f); @@ -1443,14 +1467,17 @@ public: patch_status_not_set_tm2.reset( patch_id ); halfedge_descriptor h = halfedge(f, tm2); Node_id index_p2 = get_node_id(target(h, tm2), vertex_to_node_id2); + std::array fnids = { index_p2, index_p2, index_p2 }; if (index_p2 != NID) { h=next(h, tm2); index_p2 = get_node_id(target(h, tm2), vertex_to_node_id2); + fnids[1]=index_p2; if (index_p2 != NID) { h=next(h, tm2); index_p2 = get_node_id(target(h, tm2), vertex_to_node_id2); + fnids[2]=index_p2; } } if (index_p2 != NID) @@ -1462,11 +1489,11 @@ public: } else { - // triangle which is tangent at its 3 vertices - // \todo improve this part which is not robust with a kernel - // with inexact constructions. - Bounded_side position = inside_tm1(midpoint(get(vpm2, source(h, tm2)), - get(vpm2, target(h, tm2)) )); + typename Exact_kernel::Point_3 e_centroid = + centroid(nodes.exact_node(fnids[0]), + nodes.exact_node(fnids[1]), + nodes.exact_node(fnids[2])); + Bounded_side position = inside_tm1(e_centroid); CGAL_assertion( position != ON_BOUNDARY); if ( position == in_tm1 ) is_patch_inside_tm1.set(patch_id); @@ -1474,9 +1501,7 @@ public: } else { - // TODO: tm1 might have been modified and an inexact vpm will - // provide a non-robust result. - Bounded_side position = inside_tm1( get(vpm2, target(h, tm2))); + Bounded_side position = inside_tm1( nodes.to_exact(get(vpm2, target(h, tm2)))); CGAL_assertion( position != ON_BOUNDARY); if ( position == in_tm1 ) is_patch_inside_tm1.set(patch_id); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h index 6c85bd8d8da..e34a519869f 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h @@ -146,6 +146,207 @@ void copy_edge_mark(G&, No_mark&) {} // nothing to do + +// For exact side_of_triangle_mesh +template +struct Node_vector_exact_vertex_point_map +{ +// map type definitions + typedef typename boost::property_traits::key_type key_type; + typedef typename NodeVector::Exact_kernel Exact_kernel; + typedef typename Exact_kernel::Point_3 value_type; + typedef value_type reference; + typedef boost::readable_property_map_tag category; +// internal type definitions + typedef std::size_t Node_id; + + Node_vector_exact_vertex_point_map(){} + + Node_vector_exact_vertex_point_map(const Node_id_map& node_ids, + const VertexPointMap& vpm, + const NodeVector& node_vector) + : node_ids(&node_ids) + , vpm(&vpm) + , node_vector(&node_vector) + {} + + friend value_type get(Node_vector_exact_vertex_point_map m, key_type k) + { + typename Node_id_map::const_iterator it = m.node_ids->find(k); + if (it == m.node_ids->end()) + return m.node_vector->to_exact( get(*(m.vpm), k) ); + return m.node_vector->exact_node(it->second); + } + + const Node_id_map* node_ids; + const VertexPointMap* vpm; + const NodeVector* node_vector; +}; + +// For exact side_of_triangle_mesh +template +struct Split_primitives +{ + Split_primitives(TriangleMesh& tm, PPM ppm) + : tm(tm) + , ppm(ppm) + {} + + template + void operator()(PrimitiveIterator first, + PrimitiveIterator beyond, + const CGAL::Bbox_3& bbox) const + { + typedef typename std::iterator_traits::value_type Prmtv; + PrimitiveIterator middle = first + (beyond - first)/2; + typedef typename std::iterator_traits::value_type Prmtv; + switch(TreeTraits::longest_axis(bbox)) + { + case TreeTraits::CGAL_AXIS_X: // sort along x + std::nth_element(first, middle, beyond, [this](const Prmtv& p1, const Prmtv& p2){ return get(ppm, p1.id()).x() < get(ppm,p2.id()).x(); }); + break; + case TreeTraits::CGAL_AXIS_Y: // sort along y + std::nth_element(first, middle, beyond, [this](const Prmtv& p1, const Prmtv& p2){ return get(ppm, p1.id()).y() < get(ppm,p2.id()).y(); }); + break; + case TreeTraits::CGAL_AXIS_Z: // sort along z + std::nth_element(first, middle, beyond, [this](const Prmtv& p1, const Prmtv& p2){ return get(ppm, p1.id()).z() < get(ppm,p2.id()).z(); }); + break; + default: + CGAL_error(); + } + } + TriangleMesh& tm; + PPM ppm; +}; + +// For exact side_of_triangle_mesh +template +struct Compute_bbox { + Compute_bbox(const BPM& bpm) + : bpm(bpm) + {} + + template + CGAL::Bbox_3 operator()(ConstPrimitiveIterator first, + ConstPrimitiveIterator beyond) const + { + CGAL::Bbox_3 bbox = get(bpm, first->id()); + for(++first; first != beyond; ++first) + { + bbox += get(bpm, first->id()); + } + return bbox; + } + BPM bpm; +}; + +// For exact side_of_triangle_mesh +template +struct Side_of_helper +{ + typedef Node_vector_exact_vertex_point_map VPM; + + typedef CGAL::AABB_face_graph_triangle_primitive Primitive; + typedef CGAL::AABB_traits Traits; + typedef CGAL::AABB_tree Tree_type; + + static + VPM get_vpm(const Node_id_map& node_ids, + const VertexPointMap& vpm, + const NodeVector& node_vector) + { + return VPM(node_ids, vpm, node_vector); + } + + template + static + void build_tree(TriangleMesh& tm, + Tree_type& tree, + const Node_id_map& node_ids, + FaceIdMap fid, + const VertexPointMap& vpm, + const NodeVector& node_vector) + { + typedef typename boost::graph_traits::face_descriptor face_descriptor; + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + + // add primitives + tree.insert(faces(tm).begin(), faces(tm).end(), tm, get_vpm(node_ids, vpm, node_vector)); + + // pre-build bboxes (using approximation) + std::vector face_bboxes(num_faces(tm)); + + auto get_v_box = [&node_ids, &node_vector, &vpm](vertex_descriptor v) + { + typename Node_id_map::const_iterator it = node_ids.find(v); + if (it == node_ids.end()) + return get(vpm, v).bbox(); + return approx(node_vector.exact_node(it->second)).bbox(); + }; + + for (face_descriptor f : faces(tm)) + { + halfedge_descriptor h = halfedge(f, tm); + face_bboxes[get(fid, f)] = get_v_box( source(h, tm) ) + + get_v_box( target(h, tm) ) + + get_v_box( target(next(h, tm), tm) ); + } + + typedef CGAL::Pointer_property_map::type Id_to_box; + Id_to_box id_to_box = CGAL::make_property_map(face_bboxes); + typedef Property_map_binder BPM; + BPM bpm(fid, id_to_box); + Compute_bbox compute_bbox(bpm); + + typedef One_point_from_face_descriptor_map PPM; + PPM ppm(&tm, vpm); + + Split_primitives split_primitives(tm, ppm); + tree.custom_build(compute_bbox, split_primitives); + } +}; + +template +struct Side_of_helper +{ + typedef VertexPointMap VPM; + static + VPM get_vpm(const Node_id_map&, + const VertexPointMap& vpm, + const NodeVector&) + { + return vpm; + } + + typedef CGAL::AABB_face_graph_triangle_primitive Primitive; + typedef CGAL::AABB_traits Traits; + typedef CGAL::AABB_tree Tree_type; + + + template + static + void build_tree(TriangleMesh& tm, + Tree_type& tree, + const Node_id_map& /* node_ids */, + FaceIdMap /* fid */, + const VertexPointMap& vpm, + const NodeVector& /* node_vector */) + { + tree.insert(faces(tm).begin(), faces(tm).end(), tm, vpm); + tree.build(); + } +}; + // Parts to get default property maps for output meshes based on the value type // of input vertex point maps. template @@ -424,12 +625,9 @@ struct Patch_description{ // shared_edges will be filled by halfedges pointing in the patch // that are inside `is_intersection_edge`, thus mesh boundary halfedges // are not necessarily inside. -template +template void extract_patch_simplices( - std::size_t patch_id, PolygonMesh& pm, - const FaceIndexMap fids, - const std::vector& patch_ids, std::vector::face_descriptor>& patch_faces, std::set::vertex_descriptor>& interior_vertices, std::vector::halfedge_descriptor>& interior_edges, @@ -441,22 +639,18 @@ void extract_patch_simplices( typedef typename GT::vertex_descriptor vertex_descriptor; typedef typename GT::face_descriptor face_descriptor; - for(face_descriptor f : faces(pm)) + for(face_descriptor f : patch_faces) { - if ( patch_ids[ get(fids, f) ]==patch_id ) + for(halfedge_descriptor h : + halfedges_around_face(halfedge(f, pm),pm)) { - patch_faces.push_back( f ); - for(halfedge_descriptor h : - halfedges_around_face(halfedge(f, pm),pm)) + if ( !is_intersection_edge.count(edge(h, pm)) ) { - if ( !is_intersection_edge.count(edge(h, pm)) ) - { - if ( h < opposite(h,pm) || is_border(opposite(h,pm),pm) ) - interior_edges.push_back( h ); - } - else - shared_edges.push_back(h); + if ( h < opposite(h,pm) || is_border(opposite(h,pm),pm) ) + interior_edges.push_back( h ); } + else + shared_edges.push_back(h); } } @@ -498,14 +692,19 @@ struct Patch_container{ , patch_ids(patch_ids) , fids(fids) , is_intersection_edge(is_intersection_edge) - {} + { + typedef boost::graph_traits GT; + typedef typename GT::face_descriptor face_descriptor; + + for(face_descriptor f : faces(pm)) + patches[patch_ids[ get(fids, f) ]].faces.push_back( f ); + } Patch_description& operator[](std::size_t i) { if ( !patches[i].is_initialized ) { extract_patch_simplices( - i, pm, - fids, patch_ids, + pm, patches[i].faces, patches[i].interior_vertices, patches[i].interior_edges, patches[i].shared_edges, is_intersection_edge diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_impl.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_impl.h index f30cab722ff..b95da4e4c2b 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_impl.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_impl.h @@ -411,7 +411,7 @@ class Intersection_of_triangle_meshes } Key key(ipt.type_1, ipt.type_2, h1, h2); - if (&tm1==&tm2 && h1>h2) + if (&tm1==&tm2 && h2::iterator,bool> res= 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 e85a3f6acfc..5e170ff0203 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/orientation.h @@ -53,8 +53,8 @@ namespace internal{ {} typedef bool result_type; - template - bool operator()(vertex_descriptor v1, vertex_descriptor v2) const + template + bool operator()(vertex_descriptor1 v1, vertex_descriptor2 v2) const { return CGAL::SMALLER == compare_z(get(vpmap, v1), get(vpmap, v2)); } diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h index 8a9889f9285..8254cfa4384 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h @@ -50,11 +50,12 @@ namespace CGAL { namespace Polygon_mesh_processing { namespace internal { -template +template std::array::halfedge_descriptor, 2> is_badly_shaped(const typename boost::graph_traits::face_descriptor f, TriangleMesh& tmesh, const VPM& vpm, + const VCM& vcm, const ECM& ecm, const Traits& gt, const double cap_threshold, // angle over 160° ==> cap @@ -70,58 +71,61 @@ is_badly_shaped(const typename boost::graph_traits::face_descripto halfedge_descriptor res = PMP::is_needle_triangle_face(f, tmesh, needle_threshold, parameters::vertex_point_map(vpm) .geom_traits(gt)); - if(res != null_h && !get(ecm, edge(res, tmesh))) + if(res != null_h && (!get(vcm, source(res, tmesh)) || !get(vcm, target(res, tmesh))) ) { // don't want to collapse edges that are too large - if(collapse_length_threshold == 0 || + if(collapse_length_threshold == 0 || edge_length(res, tmesh, parameters::vertex_point_map(vpm).geom_traits(gt)) <= collapse_length_threshold) { return make_array(res, null_h); } } - else // let's not make it possible to have a face be both a cap and a needle (for now) - { - res = PMP::is_cap_triangle_face(f, tmesh, cap_threshold, parameters::vertex_point_map(vpm).geom_traits(gt)); - if(res != null_h && !get(ecm, edge(res, tmesh))) - return make_array(null_h, res); - } + + res = PMP::is_cap_triangle_face(f, tmesh, cap_threshold, parameters::vertex_point_map(vpm).geom_traits(gt)); + if(res != null_h && !get(ecm, edge(res, tmesh))) + return make_array(null_h, res); return make_array(null_h, null_h); } -template +template void collect_badly_shaped_triangles(const typename boost::graph_traits::face_descriptor f, TriangleMesh& tmesh, const VPM& vpm, + const VCM& vcm, const ECM& ecm, const Traits& gt, const double cap_threshold, // angle over this threshold (as a cosine) ==> cap const double needle_threshold, // longest edge / shortest edge over this ratio ==> needle const double collapse_length_threshold, // max length of edges allowed to be collapsed - EdgeContainer& edges_to_collapse, - EdgeContainer& edges_to_flip) + HalfedgeContainer& edges_to_collapse, + HalfedgeContainer& edges_to_flip) { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - std::array res = is_badly_shaped(f, tmesh, vpm, ecm, gt, cap_threshold, + std::array res = is_badly_shaped(f, tmesh, vpm, vcm, ecm, gt, cap_threshold, needle_threshold, collapse_length_threshold); if(res[0] != boost::graph_traits::null_halfedge()) { -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA std::cout << "add new needle: " << edge(res[0], tmesh) << std::endl; #endif - edges_to_collapse.insert(edge(res[0], tmesh)); + CGAL_assertion(!is_border(res[0], tmesh)); + CGAL_assertion(!get(ecm, edge(res[0], tmesh))); + edges_to_collapse.insert(res[0]); } else // let's not make it possible to have a face be both a cap and a needle (for now) { if(res[1] != boost::graph_traits::null_halfedge()) { -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA std::cout << "add new cap: " << edge(res[1],tmesh) << std::endl; #endif - edges_to_flip.insert(edge(res[1], tmesh)); + CGAL_assertion(!is_border(res[1], tmesh)); + CGAL_assertion(!get(ecm, edge(res[1], tmesh))); + edges_to_flip.insert(res[1]); } } } @@ -254,8 +258,6 @@ get_best_edge_orientation(typename boost::graph_traits::edge_descr halfedge_descriptor h = halfedge(e, tmesh), ho = opposite(h, tmesh); - CGAL_assertion(!get(vcm, source(h, tmesh)) || !get(vcm, target(h, tmesh))); - boost::optional dv1 = get_collapse_volume(h, tmesh, vpm, gt); boost::optional dv2 = get_collapse_volume(ho, tmesh, vpm, gt); @@ -381,6 +383,9 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, typedef typename boost::property_map::type DVCM; DVCM vcm = get(Vertex_property_tag(), tmesh); + CGAL_precondition(is_valid_polygon_mesh(tmesh)); + CGAL_precondition(is_triangle_mesh(tmesh)); + for(face_descriptor f : face_range) { if(f == boost::graph_traits::null_face()) @@ -401,15 +406,22 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, } // Start the process of removing bad elements - std::set edges_to_collapse; - std::set edges_to_flip; + std::set edges_to_collapse; + std::set edges_to_flip; // @todo could probably do something a bit better by looping edges, consider the incident faces // f1 / f2 and look at f1 if f1 next_edges_to_collapse; - std::set next_edges_to_flip; + std::set next_edges_to_collapse; + std::set next_edges_to_flip; - // treat needles + // Treat needles =============================================================================== #ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA int kk=0; std::ofstream(std::string("tmp/n-00000.off")) << tmesh; #endif while(!edges_to_collapse.empty()) { - edge_descriptor e = *edges_to_collapse.begin(); + halfedge_descriptor h = *edges_to_collapse.begin(); edges_to_collapse.erase(edges_to_collapse.begin()); - CGAL_assertion(!get(ecm, e)); + CGAL_assertion(!is_border(h, tmesh)); - if(get(vcm, source(e, tmesh)) && get(vcm, target(e, tmesh))) + const edge_descriptor e = edge(h, tmesh); + CGAL_assertion(!get(ecm, edge(h, tmesh))); + + if(get(vcm, source(h, tmesh)) && get(vcm, target(h, tmesh))) continue; -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES - std::cout << " treat needle: " << e << " (" << tmesh.point(source (e, tmesh)) - << " --- " << tmesh.point(target(e, tmesh)) << ")" << std::endl; +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA + std::cout << " treat needle: " << e + << " (" << source(e, tmesh) << " " << tmesh.point(source(h, tmesh)) + << " --- " << source(e, tmesh) << " " << tmesh.point(target(h, tmesh)) << ")" << std::endl; #endif if(CGAL::Euler::does_satisfy_link_condition(e, tmesh)) { - // the following edges are removed by the collapse - halfedge_descriptor h = halfedge(e, tmesh); - CGAL_assertion(!is_border(h, tmesh)); // because extracted from a face - - std::array nc = - internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, ecm, gt, + // Verify that the element is still badly shaped + const std::array nc = + internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, vcm, ecm, gt, cap_threshold, needle_threshold, collapse_length_threshold); if(nc[0] != h) { -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES - std::cerr << "Warning: Needle criteria no longer verified " << tmesh.point(source(e, tmesh)) << " " - << tmesh.point(target(e, tmesh)) << std::endl; +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA + std::cout << "\t Needle criteria no longer verified" << std::endl; #endif - // the opposite edge might also have been inserted in the set and might still be a needle - h = opposite(h, tmesh); - if(is_border(h, tmesh)) - continue; - - nc = internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, ecm, gt, - cap_threshold, needle_threshold, - collapse_length_threshold); - if(nc[0] != h) - continue; + continue; } + // pick the orientation of edge to keep the vertex minimizing the volume variation + const halfedge_descriptor best_h = internal::get_best_edge_orientation(e, tmesh, vpm, vcm, gt); + if(best_h == boost::graph_traits::null_halfedge()) + { +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA + std::cout << "\t Geometrically invalid edge collapse!" << std::endl; +#endif + next_edges_to_collapse.insert(h); + continue; + } + + // Proceeding with the collapse, purge the sets from halfedges being removed for(int i=0; i<2; ++i) { if(!is_border(h, tmesh)) { - edge_descriptor pe = edge(prev(h, tmesh), tmesh); - edges_to_flip.erase(pe); - next_edges_to_collapse.erase(pe); - edges_to_collapse.erase(pe); + edges_to_flip.erase(h); + edges_to_collapse.erase(h); + next_edges_to_collapse.erase(h); + + halfedge_descriptor rm_h = prev(h, tmesh); + if(get(ecm, edge(rm_h, tmesh))) + rm_h = next(h, tmesh); + + edges_to_flip.erase(rm_h); + edges_to_collapse.erase(rm_h); + next_edges_to_collapse.erase(rm_h); + + halfedge_descriptor opp_rm_h = opposite(rm_h, tmesh); + edges_to_flip.erase(opp_rm_h); + edges_to_collapse.erase(opp_rm_h); + next_edges_to_collapse.erase(opp_rm_h); } h = opposite(h, tmesh); } - // pick the orientation of edge to keep the vertex minimizing the volume variation - h = internal::get_best_edge_orientation(e, tmesh, vpm, vcm, gt); - - if(h == boost::graph_traits::null_halfedge()) - { -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES - std::cerr << "Warning: geometrically invalid edge collapse! " - << tmesh.point(source(e, tmesh)) << " " - << tmesh.point(target(e, tmesh)) << std::endl; -#endif - next_edges_to_collapse.insert(e); - continue; - } - - edges_to_flip.erase(e); - next_edges_to_collapse.erase(e); // for edges added in faces incident to a vertex kept after a collapse #ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA - std::cerr << " " << kk << " -- Collapsing " << tmesh.point(source(h, tmesh)) << " " - << tmesh.point(target(h, tmesh)) << std::endl; + std::cout << " " << kk << " -- Collapsing " << tmesh.point(source(best_h, tmesh)) << " " + << tmesh.point(target(best_h, tmesh)) << std::endl; #endif + + CGAL_assertion(!get(vcm, source(best_h, tmesh))); + + // The function get_best_edge_orientation() has ensured that get(vcm, source(h, tmesh)) + // is not constrained, so get(ecm, e) is also not constrained for all e incident + // to source(h, tmesh). + // + // The function Euler::collapse_edge() removes edge(prev(h, tmesh)), but that edge + // might be constrained. In that case, next() must be removed instead. + vertex_descriptor v; + if(get(ecm, edge(prev(h, tmesh), tmesh))) + v = Euler::collapse_edge(edge(best_h, tmesh), tmesh, ecm); + else + v = Euler::collapse_edge(edge(best_h, tmesh), tmesh); + // moving to the midpoint is not a good idea. On a circle for example you might endpoint with // a bad geometry because you iteratively move one point // auto mp = midpoint(tmesh.point(source(h, tmesh)), tmesh.point(target(h, tmesh))); + // tmesh.point(v) = mp; - vertex_descriptor v = Euler::collapse_edge(edge(h, tmesh), tmesh); - - //tmesh.point(v) = mp; // examine all faces incident to the vertex kept for(halfedge_descriptor hv : halfedges_around_target(v, tmesh)) { if(!is_border(hv, tmesh)) { - internal::collect_badly_shaped_triangles(face(hv, tmesh), tmesh, vpm, ecm, gt, + internal::collect_badly_shaped_triangles(face(hv, tmesh), tmesh, vpm, vcm, ecm, gt, cap_threshold, needle_threshold, collapse_length_threshold, edges_to_collapse, edges_to_flip); } @@ -541,92 +566,84 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, #endif something_was_done = true; } - else + else // ! CGAL::Euler::does_satisfy_link_condition(e, tmesh) { -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES - std::cerr << "Warning: uncollapsable edge! " << tmesh.point(source(e, tmesh)) << " " - << tmesh.point(target(e, tmesh)) << std::endl; +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA + std::cout << "\t Uncollapsable edge!" << std::endl; #endif - next_edges_to_collapse.insert(e); + next_edges_to_collapse.insert(h); } } - // treat caps + // Treat caps ================================================================================== + CGAL_assertion(next_edges_to_flip.empty()); + #ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA kk=0; std::ofstream(std::string("tmp/c-000.off")) << tmesh; #endif while(!edges_to_flip.empty()) { - edge_descriptor e = *edges_to_flip.begin(); + halfedge_descriptor h = *edges_to_flip.begin(); edges_to_flip.erase(edges_to_flip.begin()); + CGAL_assertion(!is_border(h, tmesh)); + + const edge_descriptor e = edge(h, tmesh); CGAL_assertion(!get(ecm, e)); - if(get(vcm, source(e, tmesh)) && get(vcm, target(e, tmesh))) - continue; - -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES - std::cout << "treat cap: " << e << " (" << tmesh.point(source(e, tmesh)) - << " --- " << tmesh.point(target(e, tmesh)) << ")" << std::endl; +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA + std::cout << " treat cap: " << e + << " (" << source(e, tmesh) << " " << tmesh.point(source(h, tmesh)) + << " --- " << target(e, tmesh) << " " << tmesh.point(target(h, tmesh)) << ")" << std::endl; #endif - halfedge_descriptor h = halfedge(e, tmesh); - std::array nc = internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, ecm, gt, + std::array nc = internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, vcm, ecm, gt, cap_threshold, needle_threshold, collapse_length_threshold); - // First check the triangle is still a cap + // Check the triangle is still a cap if(nc[1] != h) { -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES - std::cerr << "Warning: Cap criteria no longer verified " << tmesh.point(source(e, tmesh)) << " --- " - << tmesh.point(target(e, tmesh)) << std::endl; +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA + std::cout << "\t Cap criteria no longer verified" << std::endl; #endif - // the opposite edge might also have been inserted in the set and might still be a cap - h = opposite(h, tmesh); - if(is_border(h, tmesh)) - continue; - - nc = internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, ecm, gt, - cap_threshold, needle_threshold, collapse_length_threshold); - if(nc[1] != h) - continue; + continue; } - // special case on the border + // special case of `edge(h, tmesh)` being a border edge --> remove the face if(is_border(opposite(h, tmesh), tmesh)) { - // remove the triangle - edges_to_flip.erase(edge(prev(h, tmesh), tmesh)); - edges_to_flip.erase(edge(next(h, tmesh), tmesh)); - next_edges_to_collapse.erase(edge(prev(h, tmesh), tmesh)); - next_edges_to_collapse.erase(edge(next(h, tmesh), tmesh)); + for(halfedge_descriptor hh : CGAL::halfedges_around_face(h, tmesh)) + { + // Remove from even 'next_edges_to_flip' because it might have been re-added from a flip + edges_to_flip.erase(hh); + next_edges_to_flip.erase(hh); + next_edges_to_collapse.erase(hh); + } + Euler::remove_face(h, tmesh); + something_was_done = true; continue; } + CGAL_assertion(!is_border(e, tmesh)); + // condition for the flip to be valid (the edge to be created does not already exist) if(!halfedge(target(next(h, tmesh), tmesh), target(next(opposite(h, tmesh), tmesh), tmesh), tmesh).second) { - if(!internal::should_flip(e, tmesh, vpm, gt)) { -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES - std::cout << "Flipping prevented: not the best diagonal" << std::endl; +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA + std::cout << "\t Flipping prevented: not the best diagonal" << std::endl; #endif - next_edges_to_flip.insert(e); + next_edges_to_flip.insert(h); continue; } -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES - std::cout << "Flipping" << std::endl; -#endif #ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA - std::cerr << "step " << kk << "\n"; - std::cerr << " Flipping " << tmesh.point(source(h, tmesh)) << " " - << tmesh.point(target(h, tmesh)) << std::endl; + std::cout << "\t step " << kk << " -- Flipping" << std::endl; #endif Euler::flip_edge(h, tmesh); CGAL_assertion(edge(h, tmesh) == e); @@ -636,33 +653,28 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, { CGAL_assertion(!is_border(h, tmesh)); std::array nc = - internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, ecm, gt, + internal::is_badly_shaped(face(h, tmesh), tmesh, vpm, vcm, ecm, gt, cap_threshold, needle_threshold, collapse_length_threshold); - if(nc[1] != boost::graph_traits::null_halfedge()) - { - if(edge(nc[1], tmesh) != e) - next_edges_to_flip.insert(edge(nc[1], tmesh)); - } - else - { - if(nc[0] != boost::graph_traits::null_halfedge()) - { - next_edges_to_collapse.insert(edge(nc[0], tmesh)); - } - } + if(nc[1] != boost::graph_traits::null_halfedge() && nc[1] != h) + next_edges_to_flip.insert(nc[1]); + else if(nc[0] != boost::graph_traits::null_halfedge()) + next_edges_to_collapse.insert(nc[0]); + h = opposite(h, tmesh); } + something_was_done = true; } -#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES - else + else // flipped edge already exists in the mesh { - std::cerr << "Warning: unflippable edge! " << tmesh.point(source(h, tmesh)) << " --- " - << tmesh.point(target(h, tmesh)) << std::endl; - next_edges_to_flip.insert(e); - } +#ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA + std::cout << "\t Unflippable edge!" << std::endl; #endif + CGAL_assertion(!is_border(h, tmesh)); + next_edges_to_flip.insert(h); + } + #ifdef CGAL_PMP_DEBUG_REMOVE_DEGENERACIES_EXTRA std::string nb = std::to_string(++kk); if(kk<10) nb = std::string("0")+nb; @@ -673,11 +685,11 @@ bool remove_almost_degenerate_faces(const FaceRange& face_range, #endif } - std::swap(edges_to_collapse, next_edges_to_collapse); - std::swap(edges_to_flip, next_edges_to_flip); - if(!something_was_done) return false; + + std::swap(edges_to_collapse, next_edges_to_collapse); + std::swap(edges_to_flip, next_edges_to_flip); } return false; @@ -1495,7 +1507,7 @@ bool remove_degenerate_edges(const EdgeRange& edge_range, face_set.insert(face(hd, tmesh)); } - CGAL_assertion(is_valid_polygon_mesh(tmesh)); + CGAL_expensive_assertion(is_valid_polygon_mesh(tmesh)); } } } @@ -1582,6 +1594,7 @@ bool remove_degenerate_faces(const FaceRange& face_range, const NamedParameters& np) { CGAL_assertion(CGAL::is_triangle_mesh(tmesh)); + CGAL_assertion(CGAL::is_valid_polygon_mesh(tmesh)); using parameters::get_parameter; using parameters::choose_parameter; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h index 24426ac86d9..15d649393f9 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/self_intersections.h @@ -47,6 +47,7 @@ #include #include #include +#include #include #ifdef DOXYGEN_RUNNING @@ -503,11 +504,21 @@ bool does_self_intersect(const FaceRange& face_range, CGAL::Emptyset_iterator unused_out; internal::self_intersections_impl(face_range, tmesh, unused_out, true /*throw*/, np); } - catch(CGAL::internal::Throw_at_output_exception&) + catch (const CGAL::internal::Throw_at_output_exception&) { return true; } - + #if defined(CGAL_LINKED_WITH_TBB) && TBB_USE_CAPTURED_EXCEPTION + catch (const tbb::captured_exception& e) + { + const char* ti1 = e.name(); + const char* ti2 = typeid(const CGAL::internal::Throw_at_output_exception&).name(); + const std::string tn1(ti1); + const std::string tn2(ti2); + if (tn1 == tn2) return true; + else throw; + } + #endif return false; } diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/shape_predicates.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/shape_predicates.h index ebfb661d346..fb05b41b819 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/shape_predicates.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/shape_predicates.h @@ -358,6 +358,8 @@ is_needle_triangle_face(typename boost::graph_traits::face_descrip const NamedParameters& np) { CGAL_precondition(threshold >= 1.); + CGAL_precondition(f != boost::graph_traits::null_face()); + CGAL_precondition(CGAL::is_triangle(halfedge(f, tm), tm)); using parameters::get_parameter; using parameters::choose_parameter; @@ -462,7 +464,8 @@ is_cap_triangle_face(typename boost::graph_traits::face_descriptor const double threshold, const NamedParameters& np) { - CGAL_precondition(CGAL::is_triangle_mesh(tm)); + CGAL_precondition(f != boost::graph_traits::null_face()); + CGAL_precondition(CGAL::is_triangle(halfedge(f, tm), tm)); CGAL_precondition(threshold >= -1.); CGAL_precondition(threshold <= 0.); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h index 4387c52030b..e936df1bff9 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/stitch_borders.h @@ -150,6 +150,7 @@ struct Dummy_cycle_rep_maintainer } // Dummies just to fit the API + void add_representative(const halfedge_descriptor) const { } void remove_representative(const halfedge_descriptor) const { } void clear_representatives() const { } @@ -214,13 +215,13 @@ public: { typedef typename boost::property_traits::reference Point_ref; - CGAL_assertion(!cycle_halfedges.empty()); - #ifdef CGAL_PMP_STITCHING_DEBUG std::cout << "update_representatives(" << cycle_halfedges.size() << ", " << filtered_stitchable_halfedges.size() << ")" << std::endl; #endif + CGAL_assertion(!cycle_halfedges.empty()); + for(const halfedge_descriptor h : cycle_halfedges) put(m_candidate_halfedges, h, true); @@ -332,17 +333,22 @@ void fill_pairs(const Halfedge& he, bool insertion_ok; std::tie(set_it, insertion_ok) = border_halfedge_map.emplace(he, std::make_pair(1,0)); - if(!insertion_ok) // we found already a halfedge with the points + if(!insertion_ok) // there is already a halfedge with the points { ++set_it->second.first; // increase the multiplicity if(set_it->second.first == 2) { + const Halfedge other_he = set_it->first; set_it->second.second = halfedge_pairs.size(); // set the id of the pair in the vector - halfedge_pairs.emplace_back(set_it->first, he); - if(get(vpm, source(he,pmesh)) == get(vpm, target(set_it->first, pmesh)) && - get(vpm, target(he,pmesh)) == get(vpm, source(set_it->first, pmesh))) + halfedge_pairs.emplace_back(other_he, he); + if(get(vpm, source(he,pmesh)) == get(vpm, target(other_he, pmesh)) && + get(vpm, target(he,pmesh)) == get(vpm, source(other_he, pmesh))) { - manifold_halfedge_pairs.push_back(true); + // Even if the halfedges are compatible, refuse to stitch if that would break the graph + if(face(opposite(he, pmesh), pmesh) == face(opposite(other_he, pmesh), pmesh)) + manifold_halfedge_pairs.push_back(false); + else + manifold_halfedge_pairs.push_back(true); } else { @@ -783,12 +789,12 @@ filter_stitchable_pairs(PolygonMesh& pmesh, } template + typename CycleRepMaintainer, typename VertexPointMap> std::size_t stitch_halfedge_range(const std::vector& to_stitch, const CandidateHalfedgeRange& representative_candidates, PolygonMesh& pmesh, - MaintainerVisitor& mv, - const VertexPointMap& vpm) + const VertexPointMap& vpm, + CycleRepMaintainer& cycle_reps_maintainer) { typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; @@ -818,7 +824,7 @@ std::size_t stitch_halfedge_range(const std::vector& to_stitch, const std::vector& to_stitch_filtered = filter_stitchable_pairs(pmesh, to_stitch, to_stitch_local, uf_vertices, uf_handles); - mv.update_representatives(representative_candidates, to_stitch_filtered, vpm); + cycle_reps_maintainer.update_representatives(representative_candidates, to_stitch_filtered, vpm); // Actually stitching run_stitch_borders(pmesh, to_stitch_filtered, vpm, uf_vertices, uf_handles); @@ -831,11 +837,11 @@ std::size_t stitch_halfedge_range(const std::vector& to_stitch, PolygonMesh& pmesh, const VertexPointMap& vpm) { - Dummy_cycle_rep_maintainer mv(pmesh); - return stitch_halfedge_range(to_stitch, halfedges(pmesh), pmesh, mv, vpm); + Dummy_cycle_rep_maintainer cycle_reps_maintainer(pmesh); + return stitch_halfedge_range(to_stitch, halfedges(pmesh), pmesh, vpm, cycle_reps_maintainer); } -//overload to avoid a useless copy +// overload to avoid a useless copy template std::size_t stitch_halfedge_range_dispatcher(const std::vector& to_stitch, PolygonMesh& pmesh, @@ -844,7 +850,7 @@ std::size_t stitch_halfedge_range_dispatcher(const std::vector& to return stitch_halfedge_range(to_stitch, pmesh, vpm); } -//overload to doing the copy +// overload making a copy template std::size_t stitch_halfedge_range_dispatcher(const HalfedgePairRange& to_stitch_const, PolygonMesh& pmesh, @@ -855,20 +861,182 @@ std::size_t stitch_halfedge_range_dispatcher(const HalfedgePairRange& to_stitch_ return stitch_halfedge_range(to_stitch, pmesh, vpm); } +// collect_duplicated_stitchable_boundary_edges() cannot handle configurations with non-manifoldness. +// However, even if non-manifoldness exists within a loop, it is safe choice to stitch consecutive +// stitchable halfedges +template +std::size_t zip_boundary_cycle(typename boost::graph_traits::halfedge_descriptor& bh, + const HalfedgeRange& cycle_halfedges, + PolygonMesh& pmesh, + const VPM vpm, + const HalfedgeKeeper& hd_kpr) +{ + typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + + std::size_t stitched_boundary_cycles_n = 0; + + // Zipping cannot change the topology of the hole so the maintenance is trivial + internal::Dummy_cycle_rep_maintainer dummy_maintainer(pmesh); + + // A boundary cycle might need to be stitched starting from different extremities + // + // v11 ------ v10 + // | | + // v0 --- v1(v13) === v2(v12) v5(v9) === v6(v8) --- v7 + // | | + // v3 ------- v4 + // + // As long as we find vertices on the boundary with both incident halfedges being compatible, + // we zip it up as much as possible. + + // not everything is always stitchable + std::set unstitchable_halfedges; + + const halfedge_descriptor null_h = boost::graph_traits::null_halfedge(); + for(;;) // until there is nothing to stitch anymore + { + if(bh == null_h) // the complete boundary cycle is stitched + break; + +#ifdef CGAL_PMP_STITCHING_DEBUG + std::cout << "Walking border from halfedge: " << edge(bh, pmesh) << std::endl; +#endif + + CGAL_assertion(is_border(bh, pmesh)); + + halfedge_descriptor hn = next(bh, pmesh), start_h = null_h; + do + { + halfedge_descriptor hnn = next(hn, pmesh); + CGAL_assertion(get(vpm, target(hn, pmesh)) == get(vpm, source(hnn, pmesh))); + + if(get(vpm, source(hn, pmesh)) == get(vpm, target(hnn, pmesh)) && + !is_degenerate_edge(edge(hn, pmesh), pmesh, parameters::vertex_point_map(vpm))) + { + if(unstitchable_halfedges.count(hn) == 0) + { + start_h = hn; + break; + } + } + + hn = hnn; + } + while(hn != bh); + + if(start_h == null_h) // nothing to be stitched on this boundary cycle + break; + +#ifdef CGAL_PMP_STITCHING_DEBUG_PP + std::cout << "Starting stitching from halfedge: " + << get(vpm, source(edge(start_h, pmesh), pmesh)) << " " + << get(vpm, target(edge(start_h, pmesh), pmesh)) << std::endl; +#endif + + CGAL_assertion(is_border(start_h, pmesh)); + + // Associate as many consecutive halfedge pairs as possible ("zipping") + std::vector > hedges_to_stitch; + + halfedge_descriptor curr_h = start_h; + halfedge_descriptor curr_hn = next(curr_h, pmesh); + for(;;) // while we can expand the zipping range + { + // Don't create an invalid polygon mesh, even if the geometry allows it + if(face(opposite(curr_h, pmesh), pmesh) == face(opposite(curr_hn, pmesh), pmesh)) + { + unstitchable_halfedges.insert(curr_h); + bh = curr_hn; + break; + } + + CGAL_assertion(is_border(curr_h, pmesh)); + CGAL_assertion(is_border(curr_hn, pmesh)); + + if(hd_kpr(curr_h, curr_hn) == curr_h) + hedges_to_stitch.emplace_back(curr_h, curr_hn); + else + hedges_to_stitch.emplace_back(curr_hn, curr_h); + +#ifdef CGAL_PMP_STITCHING_DEBUG_PP + std::cout << "expand zip with:\n" + << edge(curr_h, pmesh) << "\n\t" << source(curr_h, pmesh) << "\t(" << get(vpm, source(curr_h, pmesh)) << ")" + << "\n\t" << target(curr_h, pmesh) << "\t(" << get(vpm, target(curr_h, pmesh)) << ")\n" + << edge(curr_hn, pmesh) << "\n\t" << source(curr_hn, pmesh) << "\t(" << get(vpm, source(curr_hn, pmesh)) << ")" + << "\n\t" << target(curr_hn, pmesh) << "\t(" << get(vpm, target(curr_hn, pmesh)) << ")" << std::endl; +#endif + + // check if we have reached the end of the boundary cycle + if(prev(curr_h, pmesh) == curr_hn || prev(curr_h, pmesh) == next(curr_hn, pmesh)) + { + bh = null_h; + break; + } + + curr_h = prev(curr_h, pmesh); + curr_hn = next(curr_hn, pmesh); + + // check if the next two halfedges are not geometrically compatible + if(get(vpm, source(curr_h, pmesh)) != get(vpm, target(curr_hn, pmesh)) || + is_degenerate_edge(edge(curr_hn, pmesh), pmesh, parameters::vertex_point_map(vpm))) + { + bh = curr_hn; + break; + } + } + + // bh must be a boundary halfedge on the border that will not be impacted by any stitching + CGAL_assertion_code(if(bh != null_h) {) + CGAL_assertion_code( for(const auto& hp : hedges_to_stitch) {) + CGAL_assertion( bh != hp.first && bh != hp.second); + CGAL_assertion_code(}}) + + if(!hedges_to_stitch.empty()) + { +#ifdef CGAL_PMP_STITCHING_DEBUG_PP + std::cout << hedges_to_stitch.size() " halfedge pairs to stitch on border containing:\n" + << edge(h, pmesh) << "\n\t" << source(h, pmesh) << "\t(" << get(vpm, source(h, pmesh)) << ")" + << "\n\t" << target(h, pmesh) << "\t(" << get(vpm, target(h, pmesh)) << ")" << std::endl; +#endif + + std::size_t local_stitches = internal::stitch_halfedge_range(hedges_to_stitch, cycle_halfedges, + pmesh, vpm, dummy_maintainer); + stitched_boundary_cycles_n += local_stitches; + + if(local_stitches == 0) // refused to stitch this halfedge pair range due to manifold issue + { +#ifdef CGAL_PMP_STITCHING_DEBUG_PP + std::cout << "Failed to stitch this range!" << std::endl; +#endif + + for(const auto& hp : hedges_to_stitch) + { + unstitchable_halfedges.insert(hp.first); + unstitchable_halfedges.insert(hp.second); + } + } + } + } + + return stitched_boundary_cycles_n; +} /// High-level functions -template -std::size_t stitch_boundary_cycle(const typename boost::graph_traits::halfedge_descriptor bh, +template +std::size_t stitch_boundary_cycle(const typename boost::graph_traits::halfedge_descriptor h, PolygonMesh& pmesh, - MaintainerVisitor& mv, + CycleRepMaintainer& cycle_reps_maintainer, const CGAL_PMP_NP_CLASS& np) { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename std::pair halfedges_pair; - CGAL_precondition(bh != boost::graph_traits::null_halfedge()); - CGAL_precondition(is_border(bh, pmesh)); + CGAL_precondition(h != boost::graph_traits::null_halfedge()); + CGAL_precondition(is_border(h, pmesh)); CGAL_precondition(is_valid(pmesh)); using parameters::choose_parameter; @@ -884,18 +1052,38 @@ std::size_t stitch_boundary_cycle(const typename boost::graph_traits()); + halfedge_descriptor bh = h, bh_mem = bh; + std::vector cycle_halfedges; for(halfedge_descriptor h : halfedges_around_face(bh, pmesh)) cycle_halfedges.push_back(h); + std::size_t res = internal::zip_boundary_cycle(bh, cycle_halfedges, pmesh, vpm, hd_kpr); + if(bh == boost::graph_traits::null_halfedge()) // stitched everything + { + cycle_reps_maintainer.remove_representative(bh); + return res; + } + + // Re-compute the range if something was stitched + if(res != 0) + { + cycle_reps_maintainer.remove_representative(bh_mem); + cycle_reps_maintainer.add_representative(bh); + + cycle_halfedges.clear(); + for(halfedge_descriptor h : halfedges_around_face(bh, pmesh)) + cycle_halfedges.push_back(h); + } + std::vector to_stitch; internal::collect_duplicated_stitchable_boundary_edges(cycle_halfedges, pmesh, hd_kpr, false /*per cc*/, std::back_inserter(to_stitch), np); - mv.remove_representative(bh); + res += stitch_halfedge_range(to_stitch, cycle_halfedges, pmesh, vpm, cycle_reps_maintainer); - return stitch_halfedge_range(to_stitch, cycle_halfedges, pmesh, mv, vpm); + return res; } } //end of namespace internal @@ -920,7 +1108,7 @@ std::size_t stitch_boundary_cycle(const typename boost::graph_traits::%vertex_descriptor` /// as key type and `%Point_3` as value type} -/// \cgalParamDefault{`boost::get(CGAL::vertex_point, pm)`} +/// \cgalParamDefault{`boost::get(CGAL::vertex_point, pmesh)`} /// \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` /// must be available in `PolygonMesh`.} /// \cgalParamNEnd @@ -936,8 +1124,8 @@ std::size_t stitch_boundary_cycle(const typename boost::graph_traits mv(pmesh); - return internal::stitch_boundary_cycle(h, pmesh, mv, np); + internal::Dummy_cycle_rep_maintainer dummy_maintainer(pmesh); + return internal::stitch_boundary_cycle(h, pmesh, dummy_maintainer, np); } template @@ -950,17 +1138,17 @@ std::size_t stitch_boundary_cycle(const typename boost::graph_traits + typename CycleRepMaintainer, typename CGAL_PMP_NP_TEMPLATE_PARAMETERS> std::size_t stitch_boundary_cycles(const BorderHalfedgeRange& boundary_cycle_representatives, PolygonMesh& pmesh, - MaintainerVisitor& mv, + CycleRepMaintainer& cycle_reps_maintainer, const CGAL_PMP_NP_CLASS& np) { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; std::size_t stitched_boundary_cycles_n = 0; for(const halfedge_descriptor h : boundary_cycle_representatives) - stitched_boundary_cycles_n += stitch_boundary_cycle(h, pmesh, mv, np); + stitched_boundary_cycles_n += stitch_boundary_cycle(h, pmesh, cycle_reps_maintainer, np); return stitched_boundary_cycles_n; } @@ -988,7 +1176,7 @@ std::size_t stitch_boundary_cycles(const BorderHalfedgeRange& boundary_cycle_rep /// \cgalParamDescription{a property map associating points to the vertices of `pm`} /// \cgalParamType{a class model of `ReadWritePropertyMap` with `boost::graph_traits::%vertex_descriptor` /// as key type and `%Point_3` as value type} -/// \cgalParamDefault{`boost::get(CGAL::vertex_point, pm)`} +/// \cgalParamDefault{`boost::get(CGAL::vertex_point, pmesh)`} /// \cgalParamExtra{If this parameter is omitted, an internal property map for `CGAL::vertex_point_t` /// must be available in `PolygonMesh`.} /// \cgalParamNEnd @@ -1006,8 +1194,8 @@ std::size_t stitch_boundary_cycles(const BorderHalfedgeRange& boundary_cycle_rep { // If this API is called, we are not from stitch_borders() (otherwise there would be a maintainer) // so there is only one pass and we don't carea bout maintaining the cycle subset - internal::Dummy_cycle_rep_maintainer mv(pmesh); - return stitch_boundary_cycles(boundary_cycle_representatives, pmesh, mv, np); + internal::Dummy_cycle_rep_maintainer dummy_maintainer(pmesh); + return stitch_boundary_cycles(boundary_cycle_representatives, pmesh, dummy_maintainer, np); } ///\cond SKIP_IN_MANUAL @@ -1102,11 +1290,11 @@ std::size_t stitch_borders(PolygonMesh& pmesh, namespace internal { template std::size_t stitch_borders(const BorderHalfedgeRange& boundary_cycle_representatives, PolygonMesh& pmesh, - MaintainerVisitor& mv, + CycleRepMaintainer& cycle_maintainer, const CGAL_PMP_NP_CLASS& np) { typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; @@ -1130,35 +1318,34 @@ std::size_t stitch_borders(const BorderHalfedgeRange& boundary_cycle_representat bool per_cc = choose_parameter(get_parameter(np, internal_np::apply_per_connected_component), false); #ifdef CGAL_PMP_STITCHING_DEBUG - std::cout << "------- Stitch cycles... (" << boundary_cycle_representatives.size() << " cycle(s))" << std::endl; + std::cout << "------- Stitch cycles (#1)... (" << boundary_cycle_representatives.size() << " cycle(s))" << std::endl; #endif - std::size_t res = stitch_boundary_cycles(boundary_cycle_representatives, pmesh, mv, np); + std::size_t res = stitch_boundary_cycles(boundary_cycle_representatives, pmesh, cycle_maintainer, np); #ifdef CGAL_PMP_STITCHING_DEBUG - std::cout << "------- Stitched " << res << " in boundary cycles" << std::endl; + std::cout << "------- Stitched " << res << " halfedge pairs in boundary cycles" << std::endl; std::cout << "------- Stitch all..." << std::endl; #endif - const auto& to_consider = mv.halfedges_to_consider(); - mv.clear_representatives(); + const auto& to_consider = cycle_maintainer.halfedges_to_consider(); + cycle_maintainer.clear_representatives(); std::vector > to_stitch; internal::collect_duplicated_stitchable_boundary_edges(to_consider, pmesh, hd_kpr, per_cc, std::back_inserter(to_stitch), np); - - res += stitch_halfedge_range(to_stitch, to_consider, pmesh, mv, vpm); - - const auto& new_representatives = mv.cycle_representatives(); + res += stitch_halfedge_range(to_stitch, to_consider, pmesh, vpm, cycle_maintainer); #ifdef CGAL_PMP_STITCHING_DEBUG - std::cout << "------- Stitched " << res << " after cycles & general" << std::endl; - std::cout << "------- Stitch cycles (#2)... (" << new_representatives.size() << " cycles)" << std::endl; + std::cout << "------- Stitched " << res << " halfedge pairs after cycles & general" << std::endl; + std::cout << "------- Stitch cycles (#2)... (" << new_representatives.size() << " cycle(s))" << std::endl; #endif + const auto& new_representatives = cycle_maintainer.cycle_representatives(); + // Don't care about keeping track of the sub-cycles as this is the last pass - internal::Dummy_cycle_rep_maintainer null_mv(pmesh); - res += stitch_boundary_cycles(new_representatives, pmesh, null_mv, np); + internal::Dummy_cycle_rep_maintainer dummy_cycle_maintainer(pmesh); + res += stitch_boundary_cycles(new_representatives, pmesh, dummy_cycle_maintainer, np); #ifdef CGAL_PMP_STITCHING_DEBUG std::cout << "------- Stitched " << res << " (total)" << std::endl; @@ -1228,8 +1415,8 @@ std::size_t stitch_borders(const BorderHalfedgeRange& boundary_cycle_representat ) { // Need to keep track of the cycles since we are working on a subset of all the boundary cycles - internal::Boundary_cycle_rep_maintainer mv(pmesh); - return stitch_borders(boundary_cycle_representatives, pmesh, mv, np); + internal::Boundary_cycle_rep_maintainer cycle_reps_maintainer(pmesh); + return stitch_borders(boundary_cycle_representatives, pmesh, cycle_reps_maintainer, np); } /// \cond SKIP_IN_MANUAL @@ -1242,8 +1429,8 @@ std::size_t stitch_borders(const BorderHalfedgeRange& boundary_cycle_representat >::type* = 0) { // Need to keep track of the cycles since we are working on a subset of all the boundary cycles - internal::Boundary_cycle_rep_maintainer mv(pmesh); - return stitch_borders(boundary_cycle_representatives, pmesh, mv, parameters::all_default()); + internal::Boundary_cycle_rep_maintainer cycle_reps_maintainer(pmesh); + return stitch_borders(boundary_cycle_representatives, pmesh, cycle_reps_maintainer, parameters::all_default()); } template @@ -1256,8 +1443,8 @@ std::size_t stitch_borders(PolygonMesh& pmesh, extract_boundary_cycles(pmesh, std::back_inserter(boundary_cycle_representatives)); // We are working on all boundary cycles, so there is no need to keep track of any subset - internal::Dummy_cycle_rep_maintainer mv(pmesh); - return stitch_borders(boundary_cycle_representatives, pmesh, mv, np); + internal::Dummy_cycle_rep_maintainer dummy_maintainer(pmesh); + return stitch_borders(boundary_cycle_representatives, pmesh, dummy_maintainer, np); } template diff --git a/Polygon_mesh_processing/include/CGAL/Polyhedral_envelope.h b/Polygon_mesh_processing/include/CGAL/Polyhedral_envelope.h index 53c16127926..b1d76c12950 100644 --- a/Polygon_mesh_processing/include/CGAL/Polyhedral_envelope.h +++ b/Polygon_mesh_processing/include/CGAL/Polyhedral_envelope.h @@ -729,7 +729,7 @@ private: for (unsigned int i = 0; i < cutp.size(); i++){ const Plane& plane_i = prism[cutp[i]]; - boost::optional op = intersection_point(line, plane_i.eplane); + boost::optional op = intersection_point_for_polyhedral_envelope(line, plane_i.eplane); if(! op){ std::cout << "there must be an intersection 2" << std::endl; } @@ -850,8 +850,8 @@ private: } for (unsigned int j = 0; j < cidl.size(); j++) { - boost::optional op = intersection_point(line, - halfspace[prismindex[queue[i]]][cidl[j]].eplane); + boost::optional op = intersection_point_for_polyhedral_envelope(line, + halfspace[prismindex[queue[i]]][cidl[j]].eplane); const ePoint_3& ip = *op; inter = Implicit_Seg_Facet_interpoint_Out_Prism_return_local_id (ip, idlist, jump1, check_id); @@ -1034,7 +1034,7 @@ private: const Plane& plane_i = prism[cutp[i]]; const eLine_3& eline = *(seg[k]); - boost::optional op = intersection_point(eline, plane_i.eplane); + boost::optional op = intersection_point_for_polyhedral_envelope(eline, plane_i.eplane); if(! op){ #ifdef CGAL_ENVELOPE_DEBUG std::cout << "there must be an intersection 6" << std::endl; @@ -1088,7 +1088,7 @@ private: int inter = 0; - boost::optional ipp = intersection_point(tri_eplane, prism[cutp[i]].eplane, prism[cutp[j]].eplane); + boost::optional ipp = intersection_point_for_polyhedral_envelope(tri_eplane, prism[cutp[i]].eplane, prism[cutp[j]].eplane); if(ipp){ inter = is_3_triangle_cut_float_fast(tri0, tri1, tri2, n, @@ -1528,8 +1528,8 @@ private: if (!cut) continue; for (unsigned int j = 0; j < cidl.size(); j++) { - boost::optional op = intersection_point(eline, - halfspace[prismindex[queue[i]]][cidl[j]].eplane); + boost::optional op = intersection_point_for_polyhedral_envelope(eline, + halfspace[prismindex[queue[i]]][cidl[j]].eplane); const ePoint_3& ip = *op; inter = Implicit_Seg_Facet_interpoint_Out_Prism_return_local_id(ip, idlist, jump1, check_id); @@ -1612,8 +1612,8 @@ private: } // now we know that there exists an intesection point - boost::optional op = intersection_point(eline, - halfspace[filtered_intersection[queue[i]]][intersect_face[queue[i]][j]].eplane); + boost::optional op = intersection_point_for_polyhedral_envelope(eline, + halfspace[filtered_intersection[queue[i]]][intersect_face[queue[i]][j]].eplane); const ePoint_3& ip = *op; inter = Implicit_Seg_Facet_interpoint_Out_Prism_return_local_id_with_face_order(ip, idlist, idlistorder, jump1, check_id); @@ -1696,9 +1696,9 @@ private: // We moved the intersection here // In case there is no intersection point we continue boost::optional - op = intersection_point(etriangle_eplane, - halfspace[jump1][intersect_face[queue[i]][k]].eplane, - halfspace[jump2][intersect_face[queue[j]][h]].eplane); + op = intersection_point_for_polyhedral_envelope(etriangle_eplane, + halfspace[jump1][intersect_face[queue[i]][k]].eplane, + halfspace[jump2][intersect_face[queue[j]][h]].eplane); if(! op){ continue; } diff --git a/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h b/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h index 66db17ed253..c93f3338999 100644 --- a/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h +++ b/Polygon_mesh_processing/include/CGAL/Rigid_triangle_mesh_collision_detection.h @@ -176,6 +176,12 @@ public: : m_free_id(0) {} + //! move constructor + Rigid_triangle_mesh_collision_detection(Rigid_triangle_mesh_collision_detection&& other) + { + *this = std::move(other); + } + ~Rigid_triangle_mesh_collision_detection() { for (std::size_t k=0; k("data_stitching/boundary_cycle.off", 4); test_stitch_boundary_cycles("data_stitching/boundary_cycle_2.off", 2); test_stitch_boundary_cycles("data_stitching/complex_hole.off", 3); + test_stitch_boundary_cycles("data_stitching/folded_cycle.off", 2); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -119,9 +120,9 @@ void test_stitch_borders(const char* fname, typedef PMP::internal::Halfedges_keeper_with_marked_edge_priority Keeper; Marked_edges marks = get(Edge_property_tag(), mesh); - int id = 0; + int eid = 0; for(edge_descriptor e : edges(mesh)) - put(marks, e, (unconstrained_edge_ids.count(id++) == 0)); + put(marks, e, (unconstrained_edge_ids.count(eid++) == 0)); Keeper kpr(marks, mesh); @@ -208,7 +209,6 @@ void test_degenerate() CGAL::make_triangle(Point(0,0,0), Point(1,0,0), Point(0,1,0), tm); std::size_t res = CGAL::Polygon_mesh_processing::stitch_borders(tm); - std::cout << "Stitched: " << res << std::endl; assert(res == 0); } diff --git a/Polygonal_surface_reconstruction/include/CGAL/internal/hypothesis.h b/Polygonal_surface_reconstruction/include/CGAL/internal/hypothesis.h index af6a1cac0e5..ca4c3e6dca3 100644 --- a/Polygonal_surface_reconstruction/include/CGAL/internal/hypothesis.h +++ b/Polygonal_surface_reconstruction/include/CGAL/internal/hypothesis.h @@ -680,7 +680,7 @@ namespace CGAL { template void Hypothesis::compute_triplet_intersections() { triplet_intersections_.clear(); - if (supporting_planes_.size() < 4) // no closed surface will be constructed from less than 4 planes + if (supporting_planes_.size() < 4) // no closed surface will be constructed from fewer than 4 planes return; for (std::size_t i = 0; i < supporting_planes_.size(); ++i) { diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp index 77e50a6296b..8fb6f0a81a0 100644 --- a/Polyhedron/demo/Polyhedron/MainWindow.cpp +++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp @@ -1,3 +1,4 @@ + #ifdef CGAL_USE_SSH # include "CGAL/Use_ssh.h" #endif @@ -1794,13 +1795,16 @@ void MainWindow::updateInfo() { QString item_filename = item->property("source filename").toString(); CGAL::Bbox_3 bbox = item->bbox(); if(bbox !=CGAL::Bbox_3()) - item_text += QString("
    Bounding box: min (%1,%2,%3), max (%4,%5,%6)
    ") + item_text += QString("
    Bounding box: min (%1,%2,%3), max (%4,%5,%6), dimensions (%7, %8, %9)
    ") .arg(bbox.xmin(),0, 'g', 17) .arg(bbox.ymin(),0, 'g', 17) .arg(bbox.zmin(),0, 'g', 17) .arg(bbox.xmax(),0, 'g', 17) .arg(bbox.ymax(),0, 'g', 17) - .arg(bbox.zmax(),0, 'g', 17); + .arg(bbox.zmax(),0, 'g', 17) + .arg(bbox.xmax() - bbox.xmin(), 0, 'g', 17) + .arg(bbox.ymax() - bbox.ymin(), 0, 'g', 17) + .arg(bbox.zmax() - bbox.zmin(), 0, 'g', 17); if(!item_filename.isEmpty()) { item_text += QString("
    File: %1
    ").arg(item_filename); } @@ -2957,16 +2961,19 @@ void MainWindow::on_actionSa_ve_Scene_as_Script_triggered() last_saved_dir, "Qt Script files (*.js)"); } + if(!filename.endsWith(".js")) + filename.append(".js"); std::ofstream os(filename.toUtf8(), std::ofstream::binary); if(!os) return; - CGAL::Three::Three::CursorScopeGuard cs(Qt::WaitCursor); + QApplication::setOverrideCursor(Qt::WaitCursor); std::vector > names; std::vector > loaders; std::vector colors; std::vector rendering_modes; QStringList not_saved; Polyhedron_demo_io_plugin_interface* camera_plugin = nullptr; + QMap > group_children_map; for(int i = 0; i < scene->numberOfEntries(); ++i) { Scene_item* item = scene->item(i); @@ -2985,6 +2992,12 @@ void MainWindow::on_actionSa_ve_Scene_as_Script_triggered() if(!rem.hasMatch()) continue; ext = rem.captured(1); + //check if it is in a group + if(item->parentGroup()) + { + group_children_map[item->parentGroup()->name()].append(item->name()); + ; + } QListto_save; to_save.append(item); QString savename(tr("%1.%2").arg(item->name()).arg(ext)); @@ -2998,9 +3011,12 @@ void MainWindow::on_actionSa_ve_Scene_as_Script_triggered() } if(loader.isEmpty()) { + QApplication::restoreOverrideCursor(); QMessageBox::warning(this, "", tr("No plugin found for %1. Not saved.").arg(item->name())); + QApplication::setOverrideCursor(Qt::WaitCursor); continue; } + loaders.push_back(std::make_pair(loader, ext)); colors.push_back(item->color()); rendering_modes.push_back(item->renderingMode()); @@ -3047,6 +3063,28 @@ void MainWindow::on_actionSa_ve_Scene_as_Script_triggered() //delete temp file QFile tmp_file(fullpath); tmp_file.remove(); + //group relations + if(!group_children_map.empty()) + { + os << "var groups = ["; + for(int i = 0; i< group_children_map.size() -1; ++i) + { + QString group_name = group_children_map.keys()[i]; + os << "[\'" << group_name.toStdString().c_str()<<"\', ["; + for(int j = 0; jsetColor(QColor(Qt::blue)); - m1_over_m2_item->setName(QString("%1 - %2").arg(m1_item->name()).arg(m2_item->name())); + m1_over_m2_item->setName(QString("%2 - %1").arg(m1_item->name()).arg(m2_item->name())); CGAL::Three::Three::scene()->addItem(m1_over_m2_item); Scene_surface_mesh_item* m2_over_m1_item = new Scene_surface_mesh_item(m2_over_m1); m2_over_m1_item->setColor(QColor(Qt::red)); - m2_over_m1_item->setName(QString("%2 - %1").arg(m1_item->name()).arg(m2_item->name())); + m2_over_m1_item->setName(QString("%1 - %2").arg(m1_item->name()).arg(m2_item->name())); CGAL::Three::Three::scene()->addItem(m2_over_m1_item); Scene_surface_mesh_item* common_item = new Scene_surface_mesh_item(common); common_item->setColor(QColor(Qt::green)); 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 cada4c95506..0cb165c03f6 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PCA/Scene_edit_box_item.cpp @@ -809,12 +809,14 @@ bool Scene_edit_box_item::eventFilter(QObject *obj, QEvent *event) d->selected_vertices.push_back(d->faces[picked].vertices[i]); Kernel::Point_3 a1(d->faces[picked].vertices[1]->position()), a0(d->faces[picked].vertices[0]->position()) ,a3(d->faces[picked].vertices[3]->position()); - QVector3D a(a1.x()-a0.x(), a1.y()-a0.y(),a1.z()-a0.z()),b(a3.x()-a0.x(), a3.y()-a0.y(),a3.z()-a0.z()); - QVector3D n = QVector3D::crossProduct(a,b); + Kernel::Vector_3 a = a1 - a0, + b = a3 - a0; + Kernel::Vector_3 n = CGAL::cross_product(a,b); d->remodel_frame->setConstraint(&d->constraint); d->constraint.setTranslationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::AXIS); d->constraint.setTranslationConstraintDirection(CGAL::qglviewer::Vec(n.x(), n.y(), n.z())); + } viewer->setManipulatedFrame(d->remodel_frame); diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp index fbfdc6e1239..d0b22bb4fb3 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp @@ -939,7 +939,7 @@ void Polyhedron_demo_hole_filling_plugin::hole_filling_polyline_action() { continue; } if(it->size() < 4) { // no triangle, skip it (needs at least 3 + 1 repeat) - print_message("Warning: skipping polyline which has less than 4 points!"); + print_message("Warning: skipping polyline which has fewer than 4 points!"); continue; } diff --git a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/CMakeLists.txt b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/CMakeLists.txt index fd350a0a3d3..0591da9f770 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/CMakeLists.txt @@ -3,58 +3,61 @@ include(polyhedron_demo_macros) if(POLICY CMP0074) cmake_policy(SET CMP0074 NEW) endif() +if(NOT CGAL_DISABLE_GMP) + if(TARGET CGAL::Eigen3_support) + find_package(CGAL REQUIRED COMPONENTS Core) -if(TARGET CGAL::Eigen3_support) - find_package(CGAL REQUIRED COMPONENTS Core) + include(${CGAL_USE_FILE}) - include(${CGAL_USE_FILE}) + qt5_wrap_ui(parameterizationUI_FILES Parameterization_widget.ui OTE_dialog.ui) + polyhedron_demo_plugin(parameterization_plugin Parameterization_plugin + ${parameterizationUI_FILES}) + target_link_libraries( + parameterization_plugin PUBLIC scene_surface_mesh_item scene_textured_item + scene_selection_item CGAL::Eigen3_support) + else() + message( + STATUS + "NOTICE: Eigen 3.1 (or greater) was not found. The Parameterization plugin will not be available." + ) + endif() - qt5_wrap_ui(parameterizationUI_FILES Parameterization_widget.ui OTE_dialog.ui) - polyhedron_demo_plugin(parameterization_plugin Parameterization_plugin - ${parameterizationUI_FILES}) - target_link_libraries( - parameterization_plugin PUBLIC scene_surface_mesh_item scene_textured_item - scene_selection_item CGAL::Eigen3_support) -else() - message( - STATUS - "NOTICE: Eigen 3.1 (or greater) was not found. The Parameterization plugin will not be available." - ) -endif() - -qt5_wrap_ui(segmentationUI_FILES Mesh_segmentation_widget.ui) -polyhedron_demo_plugin(mesh_segmentation_plugin Mesh_segmentation_plugin - ${segmentationUI_FILES}) -target_link_libraries(mesh_segmentation_plugin PUBLIC scene_surface_mesh_item) + qt5_wrap_ui(segmentationUI_FILES Mesh_segmentation_widget.ui) + polyhedron_demo_plugin(mesh_segmentation_plugin Mesh_segmentation_plugin + ${segmentationUI_FILES}) + target_link_libraries(mesh_segmentation_plugin PUBLIC scene_surface_mesh_item) -qt5_wrap_ui( mesh_simplificationUI_FILES Mesh_simplification_dialog.ui) -polyhedron_demo_plugin(mesh_simplification_plugin Mesh_simplification_plugin ${mesh_simplificationUI_FILES}) -target_link_libraries(mesh_simplification_plugin PUBLIC scene_surface_mesh_item scene_selection_item) + qt5_wrap_ui( mesh_simplificationUI_FILES Mesh_simplification_dialog.ui) + polyhedron_demo_plugin(mesh_simplification_plugin Mesh_simplification_plugin ${mesh_simplificationUI_FILES}) + target_link_libraries(mesh_simplification_plugin PUBLIC scene_surface_mesh_item scene_selection_item) -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_surface_mesh_item + 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_surface_mesh_item scene_polygon_soup_item) -if(TARGET CGAL::Eigen3_support) - target_link_libraries(offset_meshing_plugin PUBLIC CGAL::Eigen3_support) -endif() -if(TARGET CGAL::TBB_support) - target_link_libraries(offset_meshing_plugin PUBLIC CGAL::TBB_support) -endif() + if(TARGET CGAL::Eigen3_support) + target_link_libraries(offset_meshing_plugin PUBLIC CGAL::Eigen3_support) + endif() + if(TARGET CGAL::TBB_support) + target_link_libraries(offset_meshing_plugin PUBLIC CGAL::TBB_support) + endif() -qt5_wrap_ui(shortestPathUI_FILES Shortest_path_widget.ui) -polyhedron_demo_plugin(shortest_path_plugin Shortest_path_plugin - ${shortestPathUI_FILES}) -target_link_libraries( - shortest_path_plugin PUBLIC scene_surface_mesh_item scene_shortest_path_item - scene_basic_objects) + qt5_wrap_ui(shortestPathUI_FILES Shortest_path_widget.ui) + polyhedron_demo_plugin(shortest_path_plugin Shortest_path_plugin + ${shortestPathUI_FILES}) + target_link_libraries( + shortest_path_plugin PUBLIC scene_surface_mesh_item scene_shortest_path_item + scene_basic_objects) -qt5_wrap_ui(basicUI_FILES Surface_mesh_approximation_dockwidget.ui) -polyhedron_demo_plugin( - surface_mesh_approximation_plugin Surface_mesh_approximation_plugin - ${basicUI_FILES} VSA_wrapper.cpp) -target_link_libraries( - surface_mesh_approximation_plugin - PUBLIC scene_surface_mesh_item scene_polygon_soup_item scene_polylines_item) + qt5_wrap_ui(basicUI_FILES Surface_mesh_approximation_dockwidget.ui) + polyhedron_demo_plugin( + surface_mesh_approximation_plugin Surface_mesh_approximation_plugin + ${basicUI_FILES} VSA_wrapper.cpp) + target_link_libraries( + surface_mesh_approximation_plugin + PUBLIC scene_surface_mesh_item scene_polygon_soup_item scene_polylines_item) +else() + message(STATUS "NOTICE: Some tests require the CGAL_Core library, and will not be compiled.") +endif() diff --git a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/VSA_wrapper.h b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/VSA_wrapper.h index 644e9fc1501..888146d8da3 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/VSA_wrapper.h +++ b/Polyhedron/demo/Polyhedron/Plugins/Surface_mesh/VSA_wrapper.h @@ -66,7 +66,7 @@ class VSA_WRAPPER_EXPORT VSA_wrapper { // fitting center Vector_3 center = CGAL::NULL_VECTOR; FT area(0.0); - for(const face_descriptor f : faces) { + for(const face_descriptor& f : faces) { center = center + (get(center_pmap, f) - CGAL::ORIGIN) * get(area_pmap, f); area += get(area_pmap, f); } diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h index 61010a23513..bb8b21b8db2 100644 --- a/Polyhedron/demo/Polyhedron/Scene.h +++ b/Polyhedron/demo/Polyhedron/Scene.h @@ -53,7 +53,7 @@ public: ~Scene(); int addItem(CGAL::Three::Scene_item* item) Q_DECL_OVERRIDE; void addChild(Scene_item* item) Q_DECL_OVERRIDE; - void changeGroup(CGAL::Three::Scene_item* item, CGAL::Three::Scene_group_item* target_group) Q_DECL_OVERRIDE; + Q_INVOKABLE void changeGroup(CGAL::Three::Scene_item* item, CGAL::Three::Scene_group_item* target_group) Q_DECL_OVERRIDE; CGAL::Three::Scene_item* replaceItem(int index, CGAL::Three::Scene_item* item, bool emit_item_about_to_be_destroyed = false) Q_DECL_OVERRIDE; Q_INVOKABLE int erase(int) Q_DECL_OVERRIDE; diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp index 3531f76919f..ab972f2653d 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp @@ -1029,6 +1029,10 @@ bool Scene_polyhedron_selection_item::treat_selection(const std::setinvalidate_aabb_tree(); + setProperty("need_invalidate_aabb_tree", false); + } invalidateOpenGLBuffers(); Q_EMIT updateInstructions("Ctrl+Right-click to move the point. \nHit Ctrl+Z to leave the selection. (2/2)"); } @@ -1953,6 +1957,7 @@ void Scene_polyhedron_selection_item::moveVertex() put(vpm, vh, Point_3(d->manipulated_frame->position().x-offset.x, d->manipulated_frame->position().y-offset.y, d->manipulated_frame->position().z-offset.z)); + setProperty("need_invalidate_aabb_tree", true); invalidateOpenGLBuffers(); poly_item->updateVertex(vh); // poly_item->invalidateOpenGLBuffers(); @@ -1972,6 +1977,10 @@ void Scene_polyhedron_selection_item::validateMoveVertex() set_highlighting(true); setProperty("need_hl_restore", false); } + if(property("need_invalidate_aabb_tree").toBool()){ + polyhedron_item()->invalidate_aabb_tree(); + setProperty("need_invalidate_aabb_tree", false); + } Q_EMIT updateInstructions("Select a vertex. (1/2)"); } diff --git a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp index 521431ada8c..86596bfa994 100644 --- a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp @@ -2410,7 +2410,7 @@ void Scene_surface_mesh_item::updateVertex(vertex_descriptor vh) getEdgeContainer(0)->getVbo(Ed::Vertices), new_point,id); - for(const auto & v_it : CGAL::vertices_around_target(vh, *face_graph())) + for(const auto v_it : CGAL::vertices_around_target(vh, *face_graph())) { EPICK::Vector_3 n = CGAL::Polygon_mesh_processing::compute_vertex_normal(v_it, *face_graph()); cgal_gl_data new_n[3]; @@ -2430,7 +2430,7 @@ void Scene_surface_mesh_item::updateVertex(vertex_descriptor vh) } - for(const auto& f_it : CGAL::faces_around_target( halfedge(vh, *face_graph()), *face_graph())) + for(const auto f_it : CGAL::faces_around_target( halfedge(vh, *face_graph()), *face_graph())) { if (f_it == boost::graph_traits::null_face()) continue; diff --git a/Polyhedron/demo/Polyhedron/Server_ws.cpp b/Polyhedron/demo/Polyhedron/Server_ws.cpp index 82bea309a37..b6d84b6d441 100644 --- a/Polyhedron/demo/Polyhedron/Server_ws.cpp +++ b/Polyhedron/demo/Polyhedron/Server_ws.cpp @@ -88,7 +88,7 @@ int main(int argc, char *argv[]) parser.addHelpOption(); QCommandLineOption portOption(QStringList() << "p" << "port", QCoreApplication::translate("main", "Port for echoserver [default: 1234]."), - QCoreApplication::translate("main", "port"), QLatin1Literal("1234")); + QCoreApplication::translate("main", "port"), QLatin1String("1234")); parser.addOption(portOption); parser.process(a); int port = parser.value(portOption).toInt(); diff --git a/Polyhedron/demo/Polyhedron/Viewer.h b/Polyhedron/demo/Polyhedron/Viewer.h index 00381648013..541674bd510 100644 --- a/Polyhedron/demo/Polyhedron/Viewer.h +++ b/Polyhedron/demo/Polyhedron/Viewer.h @@ -92,7 +92,7 @@ public: //!Set total number of depth peeling passes. void setTotalPass(int); void resetFov(); - const QVector3D& scaler() const; + const QVector3D& scaler() const override; Q_SIGNALS: void sendMessage(QString); void doneInitGL(CGAL::Three::Viewer_interface*); diff --git a/Polyhedron/demo/Polyhedron/create_sphere.h b/Polyhedron/demo/Polyhedron/create_sphere.h index a10cdbacc2b..c2fd27266d1 100644 --- a/Polyhedron/demo/Polyhedron/create_sphere.h +++ b/Polyhedron/demo/Polyhedron/create_sphere.h @@ -197,7 +197,7 @@ void create_flat_and_wire_sphere(FLOAT R, const float sectors=float(prec); const float to_rad = static_cast(CGAL_PI / 180.0); - create_flat_sphere(R, positions_spheres, normals_spheres); + create_flat_sphere(R, positions_spheres, normals_spheres, prec); float T, P; float x[4],y[4],z[4]; diff --git a/Polyhedron/demo/Polyhedron/resources/compatibility_shaders/shader_spheres.vert b/Polyhedron/demo/Polyhedron/resources/compatibility_shaders/shader_spheres.vert index 0982b0b69d9..3a54795b4b9 100644 --- a/Polyhedron/demo/Polyhedron/resources/compatibility_shaders/shader_spheres.vert +++ b/Polyhedron/demo/Polyhedron/resources/compatibility_shaders/shader_spheres.vert @@ -20,12 +20,13 @@ void main(void) for(int i=0; i<6; ++i) dist[i] = 1.0; color = vec4(colors, 1.0); - fP = mv_matrix * vertex; + vec4 transformed_vertex = + vec4(radius*vertex.x + center.x, radius* vertex.y + center.y, radius*vertex.z + center.z, 1.0); + fP = mv_matrix * transformed_vertex; mat3 norm_matrix_3; norm_matrix_3[0] = norm_matrix[0].xyz; norm_matrix_3[1] = norm_matrix[1].xyz; norm_matrix_3[2] = norm_matrix[2].xyz; fN = norm_matrix_3* normals; - gl_Position = mvp_matrix * f_matrix * - vec4(radius*vertex.x + center.x, radius* vertex.y + center.y, radius*vertex.z + center.z, 1.0) ; + gl_Position = mvp_matrix * f_matrix * transformed_vertex; } diff --git a/Polyhedron/demo/Polyhedron/resources/shader_spheres.vert b/Polyhedron/demo/Polyhedron/resources/shader_spheres.vert index 64e3097adea..68b0babf8a0 100644 --- a/Polyhedron/demo/Polyhedron/resources/shader_spheres.vert +++ b/Polyhedron/demo/Polyhedron/resources/shader_spheres.vert @@ -20,12 +20,13 @@ void main(void) for(int i=0; i<6; ++i) dist[i] = 1.0; color = vec4(colors, 1.0); - fP = mv_matrix * vertex; + vec4 transformed_vertex = + vec4(radius*vertex.x + center.x, radius* vertex.y + center.y, radius*vertex.z + center.z, 1.0); + fP = mv_matrix * transformed_vertex; mat3 norm_matrix_3; norm_matrix_3[0] = norm_matrix[0].xyz; norm_matrix_3[1] = norm_matrix[1].xyz; norm_matrix_3[2] = norm_matrix[2].xyz; fN = norm_matrix_3* normals; - gl_Position = mvp_matrix * f_matrix * - vec4(radius*vertex.x + center.x, radius* vertex.y + center.y, radius*vertex.z + center.z, 1.0) ; + gl_Position = mvp_matrix * f_matrix * transformed_vertex; } diff --git a/Polyhedron/include/CGAL/IO/Polyhedron_scan_OFF.h b/Polyhedron/include/CGAL/IO/Polyhedron_scan_OFF.h index ce4acc9f5bf..51935383f32 100644 --- a/Polyhedron/include/CGAL/IO/Polyhedron_scan_OFF.h +++ b/Polyhedron/include/CGAL/IO/Polyhedron_scan_OFF.h @@ -114,7 +114,7 @@ void Polyhedron_scan_OFF:: operator()(HDS& target) std::cerr << " " << std::endl; std::cerr << "Polyhedron_scan_OFF::" << std::endl; std::cerr << "operator()(): input error: facet " << i - << " has less than 3 vertices." << std::endl; + << " has fewer than 3 vertices." << std::endl; } B.rollback(); diff --git a/Polyline_simplification_2/doc/Polyline_simplification_2/Polyline_simplification_2.txt b/Polyline_simplification_2/doc/Polyline_simplification_2/Polyline_simplification_2.txt index 63a0387263f..1900522d579 100644 --- a/Polyline_simplification_2/doc/Polyline_simplification_2/Polyline_simplification_2.txt +++ b/Polyline_simplification_2/doc/Polyline_simplification_2/Polyline_simplification_2.txt @@ -167,6 +167,16 @@ over all vertices of all polyline constraints. \cgalExample{Polyline_simplification_2/simplify.cpp} +Note that when polylines share subsequences of polyline vertices they can get simplified simultaneously. + +\cgalFigureBegin{figure_overlapping_polylines, overlapping_polylines.png} +Simplification of overlapping subsequence of polyline vertices +\cgalFigureEnd + +\cgalExample{Polyline_simplification_2/simplify_overlapping_polylines.cpp} + + + \subsection Subsection_PolylineSimplification_Keeping Keeping Points While Removing Vertices diff --git a/Polyline_simplification_2/doc/Polyline_simplification_2/examples.txt b/Polyline_simplification_2/doc/Polyline_simplification_2/examples.txt index a0713d4fd20..4f5338858ee 100644 --- a/Polyline_simplification_2/doc/Polyline_simplification_2/examples.txt +++ b/Polyline_simplification_2/doc/Polyline_simplification_2/examples.txt @@ -1,6 +1,7 @@ /*! \example Polyline_simplification_2/simplify_polygon.cpp \example Polyline_simplification_2/simplify.cpp +\example Polyline_simplification_2/simplify_overlapping_polylines.cpp \example Polyline_simplification_2/simplify_terrain.cpp \example Polyline_simplification_2/points_and_vertices.cpp */ diff --git a/Polyline_simplification_2/doc/Polyline_simplification_2/fig/overlapping_polylines.png b/Polyline_simplification_2/doc/Polyline_simplification_2/fig/overlapping_polylines.png new file mode 100644 index 00000000000..83b27735ab3 Binary files /dev/null and b/Polyline_simplification_2/doc/Polyline_simplification_2/fig/overlapping_polylines.png differ diff --git a/Polyline_simplification_2/examples/Polyline_simplification_2/simplify_overlapping_polylines.cpp b/Polyline_simplification_2/examples/Polyline_simplification_2/simplify_overlapping_polylines.cpp new file mode 100644 index 00000000000..96fa16269a3 --- /dev/null +++ b/Polyline_simplification_2/examples/Polyline_simplification_2/simplify_overlapping_polylines.cpp @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include +#include + +namespace PS = CGAL::Polyline_simplification_2; + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; + +typedef PS::Vertex_base_2 Vb; +typedef CGAL::Constrained_triangulation_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 TDS; +typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; +typedef CGAL::Constrained_triangulation_plus_2 CT; + +typedef CT::Point Point; +typedef CT::Constraint_iterator Constraint_iterator; +typedef CT::Vertices_in_constraint_iterator Vertices_in_constraint_iterator; +typedef CT::Points_in_constraint_iterator Points_in_constraint_iterator; +typedef PS::Stop_below_count_ratio_threshold Stop; +typedef PS::Squared_distance_cost Cost; + +int main() +{ + CT ct; + + std::vector P = { Point(0,1), Point(1,1), Point(2,2), Point(3,1), Point(4,1), Point(4,2), Point(4,1), Point(5,1) }; + std::vector Q = { Point(5,0), Point(4,1), Point(3,1), Point(2,2), Point(1,1), Point(0,0) }; + std::vector R = { Point(3,1), Point(4,1) }; + + ct.insert_constraint(P); + ct.insert_constraint(Q); + ct.insert_constraint(R); + + PS::simplify(ct, Cost(), Stop(0.5)); + + for(Constraint_iterator cit = ct.constraints_begin(); + cit != ct.constraints_end(); + ++cit) { + std::cout << "simplified polyline" << std::endl; + for(Points_in_constraint_iterator vit = + ct.points_in_constraint_begin(*cit); + vit != ct.points_in_constraint_end(*cit); + ++vit) + std::cout << *vit << std::endl; + } + return 0; +} diff --git a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Vertex_base_2.h b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Vertex_base_2.h index b1d090583f8..d5f2856e239 100644 --- a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Vertex_base_2.h +++ b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/Vertex_base_2.h @@ -37,6 +37,9 @@ class Vertex_base_2 bool m_removable; FT m_cost; +public: + std::size_t ID; + #ifndef DOXYGEN_RUNNING public: template < typename TDS2 > diff --git a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h index 2b6aca31f9f..ee681c767d4 100644 --- a/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h +++ b/Polyline_simplification_2/include/CGAL/Polyline_simplification_2/simplify.h @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -57,11 +58,15 @@ class Polyline_simplification_2 public: typedef typename PCT::Point Point; + typedef typename PCT::Edge Edge; typedef typename PCT::Constraint_id Constraint_id; + typedef typename PCT::Constrained_edges_iterator Constrained_edges_iterator; typedef typename PCT::Constraint_iterator Constraint_iterator; typedef typename PCT::Vertices_in_constraint_iterator Vertices_in_constraint_iterator; + typedef typename PCT::Finite_vertices_iterator Finite_vertices_iterator; //typedef typename PCT::Points_in_constraint_iterator Points_in_constraint_iterator; typedef typename PCT::Vertex_handle Vertex_handle; + typedef typename PCT::Face_handle Face_handle; typedef typename PCT::Vertex_circulator Vertex_circulator; typedef typename PCT::Geom_traits::FT FT; @@ -71,6 +76,7 @@ public: StopFunction stop; std::size_t pct_initial_number_of_vertices, number_of_unremovable_vertices; + std::unordered_map > vertex_to_iterator; struct Compare_cost { @@ -79,6 +85,12 @@ public: { return (*x)->cost() < (*y)->cost(); } + + bool operator() (const Vertex_handle& x,const Vertex_handle& y) const + { + return x->cost() < y->cost(); + } + } ; struct Id_map : public boost::put_get_helper @@ -86,12 +98,16 @@ public: typedef boost::readable_property_map_tag category; typedef std::size_t value_type; typedef value_type reference; - typedef Vertices_in_constraint_iterator key_type; + typedef Vertex_handle key_type; - reference operator[] ( key_type const& x ) const { return x.base()->id ; } + + reference operator[] ( key_type const& x ) const + { + return x->ID; + } } ; - typedef CGAL::Modifiable_priority_queue MPQ ; + typedef CGAL::Modifiable_priority_queue MPQ ; MPQ* mpq; @@ -124,24 +140,64 @@ public: delete mpq; } + // endpoints of constraints are unremovable + // vertices which are not endpoint and have != 2 incident constrained edges are unremovable void initialize_unremovable() { - std::set vertices; Constraint_iterator cit = pct.constraints_begin(), e = pct.constraints_end(); for(; cit!=e; ++cit){ Constraint_id cid = *cit; - Vertices_in_constraint_iterator it = pct.vertices_in_constraint_begin(cid); + Vertices_in_constraint_iterator it = pct.vertices_in_constraint_begin(cid), + ite = pct.vertices_in_constraint_end(cid); (*it)->set_removable(false); - for(; it != pct.vertices_in_constraint_end(cid); ++it){ - if(vertices.find(*it) != vertices.end()){ + ++it; + for(; it != ite; ++it){ + if((boost::next(it) != ite) && (boost::prior(it)== boost::next(it))){ (*it)->set_removable(false); - } else { - vertices.insert(*it); } } it = boost::prior(it); (*it)->set_removable(false); } + + std::unordered_map degrees; + for (Constrained_edges_iterator it = pct.constrained_edges_begin(); it != pct.constrained_edges_end(); ++it) { + Edge e = *it; + Face_handle fh = e.first; + int ei = e.second; + Vertex_handle vh = fh->vertex(pct.cw(ei)); + ++degrees[vh]; + vh = fh->vertex(pct.ccw(ei)); + ++degrees[vh]; + } + + for(Finite_vertices_iterator it = pct.finite_vertices_begin(); it != pct.finite_vertices_end(); ++it){ + if( it->is_removable() && (degrees[it] != 2) ){ + it->set_removable(false); + } + } + + cit = pct.constraints_begin(), e = pct.constraints_end(); + for(; cit!=e; ++cit){ + Constraint_id cid = *cit; + for(Vertices_in_constraint_iterator it = pct.vertices_in_constraint_begin(cid); + it != pct.vertices_in_constraint_end(cid); + ++it){ + if((*it)->is_removable()){ + typename std::unordered_map >::iterator lit; + lit = vertex_to_iterator.find(*it); + + if(lit != vertex_to_iterator.end()){ + std::list& ilist = lit->second; + if(std::find(ilist.begin(),ilist.end(),it) == ilist.end()){ + ilist.push_back(it); + } + }else{ + vertex_to_iterator[*it].push_back(it); + } + } + } + } } // For all polyline constraints we compute the cost of all unremovable and not removed vertices @@ -156,7 +212,9 @@ public: boost::optional dist = cost(pct, it); if(dist){ (*it)->set_cost(*dist); - (*mpq).push(it); + if(! (*mpq).contains(*it)){ + (*mpq).push(*it); + } ++n; } else { // no need to set the costs as this vertex is not in the priority queue @@ -230,7 +288,9 @@ public: for(Vertices_in_constraint_iterator it = pct.vertices_in_constraint_begin(cid); it != pct.vertices_in_constraint_end(cid); ++it){ - it.base()->id = id++; + Vertex_handle vh = *it; + vh->ID = id++; + //vertex_index_map[vh] = id++; } return id; } @@ -239,9 +299,9 @@ public: initialize_indices() { int id = 0; - Constraint_iterator b = pct.constraints_begin(), e = pct.constraints_end(); - for(; b!=e; ++b){ - id = initialize_indices(*b, id); + + for(Finite_vertices_iterator it = pct.finite_vertices_begin(); it != pct.finite_vertices_end(); ++it){ + it->ID = id++; } return id; } @@ -252,29 +312,31 @@ operator()() if((*mpq).empty()){ return false; } - Vertices_in_constraint_iterator v = (*mpq).top(); + Vertex_handle v = (*mpq).top(); (*mpq).pop(); - if(stop(pct, *v, (*v)->cost(), pct_initial_number_of_vertices, pct.number_of_vertices())){ + if(stop(pct, v, v->cost(), pct_initial_number_of_vertices, pct.number_of_vertices())){ return false; } - if(is_removable(v)){ - Vertices_in_constraint_iterator u = boost::prior(v), w = boost::next(v); - pct.simplify(v); + + Vertices_in_constraint_iterator vit = vertex_to_iterator[v].front(); + if(is_removable(vit)){ + Vertices_in_constraint_iterator u = boost::prior(vit), w = boost::next(vit); + pct.simplify(vit); if((*u)->is_removable()){ boost::optional dist = cost(pct, u); if(! dist){ // cost is undefined - if( mpq->contains(u) ){ - mpq->erase(u); + if( mpq->contains(*u) ){ + mpq->erase(*u); } } else { (*u)->set_cost(*dist); - if(mpq->contains(u)){ - mpq->update(u, true); + if(mpq->contains(*u)){ + mpq->update(*u, true); } else{ - mpq->push(u); + mpq->push(*u); } } } @@ -283,16 +345,16 @@ operator()() boost::optional dist = cost(pct, w); if(! dist){ // cost is undefined - if( mpq->contains(w) ){ - mpq->erase(w); + if( mpq->contains(*w) ){ + mpq->erase(*w); } } else { (*w)->set_cost(*dist); - if(mpq->contains(w)){ - mpq->update(w, true); + if(mpq->contains(*w)){ + mpq->update(*w, true); } else{ - mpq->push(w); + mpq->push(*w); } } diff --git a/Property_map/include/CGAL/property_map.h b/Property_map/include/CGAL/property_map.h index affbadb93b6..8fce0f606fd 100644 --- a/Property_map/include/CGAL/property_map.h +++ b/Property_map/include/CGAL/property_map.h @@ -469,7 +469,7 @@ struct Constant_property_map typedef KeyType key_type; typedef ValueType value_type; - typedef value_type& reference; + typedef const value_type& reference; typedef boost::read_write_property_map_tag category; Constant_property_map(const value_type& default_value = value_type()) : default_value (default_value) { } diff --git a/STL_Extension/include/CGAL/Multiset.h b/STL_Extension/include/CGAL/Multiset.h index 389880ded7c..5be3bc3b41c 100644 --- a/STL_Extension/include/CGAL/Multiset.h +++ b/STL_Extension/include/CGAL/Multiset.h @@ -1196,7 +1196,7 @@ public: /*! * Split the tree such that all remaining objects are less than a given - * key, and all objects greater then (or equal to) this key form + * key, and all objects greater than (or equal to) this key form * a new output tree. [takes O(log n) operations] * \param key The split key. * \param comp_key A comparison functor for comparing keys and objects. diff --git a/STL_Extension/include/CGAL/hash_openmesh.h b/STL_Extension/include/CGAL/hash_openmesh.h index bab5dc40918..700f58e87eb 100644 --- a/STL_Extension/include/CGAL/hash_openmesh.h +++ b/STL_Extension/include/CGAL/hash_openmesh.h @@ -43,7 +43,10 @@ public: } bool - operator!=(const OMesh_edge& other) { return !(*this == other); } + operator!=(const OMesh_edge& other) const + { + return !(*this == other); + } Halfedge_handle opposite() const { return Halfedge_handle((halfedge_.idx() & 1) ? halfedge_.idx()-1 : halfedge_.idx()+1); } @@ -73,7 +76,7 @@ inline std::size_t hash_value(const CGAL::internal::OMesh_edge @@ -87,6 +90,8 @@ namespace std { #ifndef CGAL_CFG_NO_STD_HASH +#ifndef OM_HAS_HASH + template <> struct hash : public CGAL::cpp98::unary_function @@ -131,16 +136,6 @@ struct hash } }; -template <> -struct hash > - : public CGAL::cpp98::unary_function -{ - - std::size_t operator()(const CGAL::internal::OMesh_edge& h) const - { - return h.idx(); - } -}; template <> struct hash @@ -153,6 +148,20 @@ struct hash } }; +#endif // OM_HAS_HASH + +template +struct hash > + : public CGAL::cpp98::unary_function, std::size_t> +{ + + std::size_t operator()(const CGAL::internal::OMesh_edge& h) const + { + return h.idx(); + } +}; + + #endif // CGAL_CFG_NO_STD_HASH #if defined(BOOST_MSVC) @@ -162,6 +171,6 @@ struct hash } // namespace std -#endif // OM_HAS_HASH + #endif // CGAL_HASH_OPENMESH_H diff --git a/STL_Extension/test/STL_Extension/CMakeLists.txt b/STL_Extension/test/STL_Extension/CMakeLists.txt index f54723a483a..6c45f1a551f 100644 --- a/STL_Extension/test/STL_Extension/CMakeLists.txt +++ b/STL_Extension/test/STL_Extension/CMakeLists.txt @@ -9,6 +9,16 @@ find_package(CGAL REQUIRED) find_package( TBB QUIET ) include(CGAL_TBB_support) +find_package(OpenMesh QUIET) + +if(OpenMesh_FOUND) + include(UseOpenMesh) + add_definitions(-DCGAL_USE_OPENMESH) +else() + message(STATUS "Tests that use OpenMesh will not be compiled.") +endif() + + create_single_source_cgal_program( "test_Boolean_tag.cpp" ) create_single_source_cgal_program( "test_Cache.cpp" ) create_single_source_cgal_program( "test_Compact_container.cpp" ) @@ -49,3 +59,8 @@ create_single_source_cgal_program( "test_for_each.cpp" ) if(TARGET CGAL::TBB_support) target_link_libraries(test_for_each PUBLIC CGAL::TBB_support) endif() + +if(OpenMesh_FOUND) + create_single_source_cgal_program("test_hash_OpenMesh.cpp") + target_link_libraries(test_hash_OpenMesh PRIVATE ${OPENMESH_LIBRARIES}) +endif() diff --git a/STL_Extension/test/STL_Extension/test_hash_OpenMesh.cpp b/STL_Extension/test/STL_Extension/test_hash_OpenMesh.cpp new file mode 100644 index 00000000000..a13f4d78a75 --- /dev/null +++ b/STL_Extension/test/STL_Extension/test_hash_OpenMesh.cpp @@ -0,0 +1,36 @@ +#include + + +#include +#include +#include + +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; + +typedef OpenMesh::TriMesh_ArrayKernelT Mesh; + + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; +typedef boost::graph_traits::face_descriptor face_descriptor; +typedef boost::graph_traits::halfedge_descriptor halfedge_descriptor; +typedef boost::graph_traits::edge_descriptor edge_descriptor; + +int main() +{ + { + std::unordered_map vmap; + std::unordered_map hmap; + std::unordered_map emap; + std::unordered_map fmap; + } + { + boost::unordered_map vmap; + boost::unordered_map hmap; + boost::unordered_map emap; + boost::unordered_map fmap; + } + return 0; +} diff --git a/Scripts/developer_scripts/tag_pr_per_release.sh b/Scripts/developer_scripts/tag_pr_per_release.sh index a8927dcfe17..36e8c56e859 100644 --- a/Scripts/developer_scripts/tag_pr_per_release.sh +++ b/Scripts/developer_scripts/tag_pr_per_release.sh @@ -30,7 +30,7 @@ REMOTE=`git config branch.releases/CGAL-${PREVIOUS_MAJOR_RELEASE}-branch.remote # Call git-fetch to refresh the branch, and fetch the references # refs/pull/*/head as well. -git fetch --tags "${REMOTE}" `git config "remote.${REMOTE}.fetch"` 'refs/pull/*/head:refs/pull/*/head' +git fetch --tags "${REMOTE}" `git config --get-all "remote.${REMOTE}.fetch"` '+refs/pull/*/head:refs/pull/*/head' PR_LIST=`git log --pretty='%D' v${PREVIOUS_MAJOR_RELEASE}..v${CURRENT_RELEASE} | awk 'match($0, /refs\/pull\/([0-9]+)\/head/, a) {print a[1]}' | sort -u` diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h index 9aa16d3a72c..55d5ea7bc7f 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_2.h @@ -6,12 +6,28 @@ namespace CGAL { The class `Segment_Delaunay_graph_2` represents the segment Delaunay graph (which is the dual graph of the 2D segment Voronoi diagram). -Currently it supports only insertions of sites. +Currently it only supports the insertions of sites. -\tparam Gt must be a model of `SegmentDelaunayGraphTraits_2` -\tparam DS must be a model of `SegmentDelaunayGraphDataStructure_2`. -`DS` defaults to -`CGAL::Triangulation_data_structure_2< CGAL::Segment_Delaunay_graph_vertex_base_2, CGAL::Triangulation_face_base_2 >`. +\tparam Gt must be a model of `SegmentDelaunayGraphTraits_2`. + +\tparam St must be a model of `SegmentDelaunayGraphStorageTraits_2`. + By default, the storage traits is instantiated by `Segment_Delaunay_graph_storage_traits_2`. + +\tparam DS must be a model of `SegmentDelaunayGraphDataStructure_2` whose vertex and face are + models of the concepts `SegmentDelaunayGraphVertexBase_2` and `TriangulationFaceBase_2`, respectively. + It defaults to: + \code + `CGAL::Triangulation_data_structure_2< + CGAL::Segment_Delaunay_graph_vertex_base_2, + CGAL::Segment_Delaunay_graph_face_base_2 >` + \endcode + +\cgalHeading{Storage} + +To avoid redundancy in the storage of points, input points are stored in a container, +and the various types of sites (input points and segments, points of intersection, +subsegments with one or two points of intersection as endpoints) only store handles to the points +in the container. See Section \ref Segment_Delaunay_graph_2StronglyIntersecting for more information. \cgalHeading{Traversal of the Segment Delaunay Graph} @@ -19,45 +35,34 @@ A segment Delaunay graph can be seen as a container of faces and vertices. Therefore the `Segment_Delaunay_graph_2` class provides several iterators and circulators that allow to traverse it (completely or partially). - - \cgalModels `DelaunayGraph_2` -\sa `DelaunayGraph_2` -\sa `SegmentDelaunayGraphTraits_2` -\sa `SegmentDelaunayGraphDataStructure_2` -\sa `SegmentDelaunayGraphVertexBase_2` -\sa `TriangulationFaceBase_2` -\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` \sa `CGAL::Segment_Delaunay_graph_traits_2` \sa `CGAL::Segment_Delaunay_graph_traits_without_intersections_2` \sa `CGAL::Segment_Delaunay_graph_filtered_traits_2` \sa `CGAL::Segment_Delaunay_graph_filtered_traits_without_intersections_2` -\sa `CGAL::Triangulation_data_structure_2` -\sa `CGAL::Segment_Delaunay_graph_vertex_base_2` -\sa `CGAL::Triangulation_face_base_2` - +\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` */ -template< typename Gt, typename DS > +template< typename Gt, typename St, typename DS > class Segment_Delaunay_graph_2 { public: /// \name Types - - - - /// @{ /*! -A type for the geometric traits. +Type for the geometric traits. */ typedef Gt Geom_traits; /*! -A type for the underlying -data structure. +Type for the storage traits. +*/ +typedef St Storage_traits; + +/*! +Type for the underlying data structure. */ typedef DS Data_structure; @@ -73,26 +78,29 @@ Size type (an unsigned integral type) typedef typename DS::size_type size_type; /*! -A type for the -point defined in the geometric traits. +Type for the point defined in the geometric traits. */ typedef typename Gt::Point_2 Point_2; /*! -A type for the segment Delaunay graph site, defined in the geometric -traits. +Type for the segment Delaunay graph site, defined in the geometric traits. */ typedef typename Gt::Site_2 Site_2; /*! -A type for the container of points. +Type for the segment Delaunay storage site, defined in the storage traits. */ -typedef unspecified_type Point_container; +typedef typename Storage_traits::Storage_site_2 Storage_site_2; /*! -A handle for points in the point container. +Type for the container of points. */ -typedef typename Point_container::iterator Point_handle; +typedef typename Storage_traits::Point_container Point_container; + +/*! +Handle type for points in the point container. +*/ +typedef typename Storage_traits::Point_handle Point_handle; /// @} @@ -125,67 +133,67 @@ The `Edge(f,i)` is the edge common to faces `f` and typedef typename DS::Edge Edge; /*! -A type for a vertex. +Type for a vertex. */ typedef typename DS::Vertex Vertex; /*! -A type for a face. +Type for a face. */ typedef typename DS::Face Face; /*! -A type for a handle to a vertex. +Type for a handle to a vertex. */ typedef typename DS::Vertex_handle Vertex_handle; /*! -A type for a handle to a face. +Type for a handle to a face. */ typedef typename DS::Face_handle Face_handle; /*! -A type for a circulator over vertices incident to a given vertex. +Type for a circulator over vertices incident to a given vertex. */ typedef typename DS::Vertex_circulator Vertex_circulator; /*! -A type for a circulator over faces incident to a given vertex. +Type for a circulator over faces incident to a given vertex. */ typedef typename DS::Face_circulator Face_circulator; /*! -A type for a circulator over edges incident to a given vertex. +Type for a circulator over edges incident to a given vertex. */ typedef typename DS::Edge_circulator Edge_circulator; /*! -A type for an iterator over all vertices. +Type for an iterator over all vertices. */ typedef typename DS::Vertex_iterator All_vertices_iterator; /*! -A type for an iterator over all faces. +Type for an iterator over all faces. */ typedef typename DS::Face_iterator All_faces_iterator; /*! -A type for an iterator over all edges. +Type for an iterator over all edges. */ typedef typename DS::Edge_iterator All_edges_iterator; /*! -A type for an iterator over finite vertices. +Type for an iterator over finite vertices. */ typedef unspecified_type Finite_vertices_iterator; /*! -A type for an iterator over finite faces. +Type for an iterator over finite faces. */ typedef unspecified_type Finite_faces_iterator; /*! -A type for an iterator over finite edges. +Type for an iterator over finite edges. */ typedef unspecified_type Finite_edges_iterator; @@ -204,12 +212,12 @@ typedef unspecified_type Finite_edges_iterator; /// @{ /*! -A type for a bidirectional iterator over all input sites. +Type for a bidirectional iterator over all input sites. */ typedef unspecified_type Input_sites_iterator; /*! -A type for a bidirectional iterator over all output sites (the sites +Type for a bidirectional iterator over all output sites (the sites in the Delaunay graph). */ typedef unspecified_type Output_sites_iterator; @@ -222,19 +230,19 @@ typedef unspecified_type Output_sites_iterator; /// @{ /*! -Creates the -segment Delaunay graph using `gt` as geometric traits. +Creates the segment Delaunay graph using `gt` as geometric traits and `st` as storage traits. */ -Segment_Delaunay_graph_2(Gt gt=Gt()); +Segment_Delaunay_graph_2(Gt gt=Gt(), St st=St()); /*! -Creates the segment Delaunay graph using `gt` as geometric traits +Creates the segment Delaunay graph using `gt` as geometric traits, `st` as storage traits, and inserts all sites in the range [`first`, `beyond`). -\pre `Input_iterator` must be a model of `InputIterator`. The value type of `Input_iterator` must be either `Point_2` or `Site_2`. +\pre `Input_iterator` must be a model of `InputIterator`. +The value type of `Input_iterator` must be either `Point_2` or `Site_2`. */ template< class Input_iterator > Segment_Delaunay_graph_2(Input_iterator first, Input_iterator beyond, -Gt gt=Gt()); + Gt gt = Gt(), St gt = St()); /// @} @@ -242,9 +250,30 @@ Gt gt=Gt()); /// @{ /*! -Returns a reference to the segment Delaunay graph traits object. +Returns a reference to the segment Delaunay graph geometric traits object. */ -Geom_traits geom_traits(); +const Geom_traits& geom_traits() const; + +/*! +Returns a reference to the segment Delaunay graph storage traits object. +*/ +const Storage_traits& storage_traits() const; + +/*! +Returns a reference to the point container object. +*/ +const Point_container& point_container() const; + +/*! +Returns a reference to the +segment Delaunay graph data structure object. +*/ +const Data_structure& data_structure() const; + +/*! +Same as `data_structure()`. It has been added for compliance to the `DelaunayGraph_2` concept. +*/ +const Data_structure& tds() const; /*! Returns the dimension of the segment Delaunay graph. The dimension @@ -252,64 +281,45 @@ is \f$ -1\f$ if the graph contains no sites, \f$ 0\f$ if the graph contains one site, \f$ 1\f$ if it contains two sites and \f$ 2\f$ if it contains three or more sites. */ -int dimension(); +int dimension() const; /*! Returns the number of finite vertices of the segment Delaunay graph. */ -size_type number_of_vertices(); +size_type number_of_vertices() const; /*! Returns the number of faces (both finite and infinite) of the segment Delaunay graph. */ -size_type number_of_faces(); +size_type number_of_faces() const; /*! Return the number of input sites. */ -size_type number_of_input_sites(); +size_type number_of_input_sites() const; /*! Return the number of output sites. This is equal to the number of vertices in the segment Delaunay graph. */ -size_type number_of_output_sites(); +size_type number_of_output_sites() const; /*! Returns a face incident to the `infinite_vertex`. */ -Face_handle infinite_face(); +Face_handle infinite_face() const; /*! Returns the `infinite_vertex`. */ -Vertex_handle -infinite_vertex(); +Vertex_handle infinite_vertex() const; /*! Returns a vertex distinct from the `infinite_vertex`. \pre The number of sites in the segment Delaunay graph must be at least one. */ -Vertex_handle finite_vertex(); - -/*! -Returns a reference to the -segment Delaunay graph data structure object. -*/ -Data_structure data_structure(); - -/*! -Same as `data_structure()`. It -has been added for compliance to the `DelaunayGraph_2` concept. -*/ -Data_structure tds(); - -/*! -Returns a reference to -the point container object. -*/ -Point_container point_container(); +Vertex_handle finite_vertex() const; /// @} @@ -324,33 +334,32 @@ Point_container point_container(); /*! Starts at an arbitrary finite vertex. */ -Finite_vertices_iterator finite_vertices_begin(); +Finite_vertices_iterator finite_vertices_begin() const; /*! Past-the-end iterator. */ -Finite_vertices_iterator finite_vertices_end(); +Finite_vertices_iterator finite_vertices_end() const; /*! Starts at an arbitrary finite edge. */ -Finite_edges_iterator finite_edges_begin(); +Finite_edges_iterator finite_edges_begin() const; /*! Past-the-end iterator. */ -Finite_edges_iterator finite_edges_end(); +Finite_edges_iterator finite_edges_end() const; /*! Starts at an arbitrary finite face. */ -Finite_faces_iterator finite_faces_begin(); +Finite_faces_iterator finite_faces_begin() const; /*! Past-the-end iterator. */ -Finite_faces_iterator finite_faces_end() -const; +Finite_faces_iterator finite_faces_end() const; /// @} @@ -366,32 +375,32 @@ const; /*! Starts at an arbitrary vertex. */ -All_vertices_iterator all_vertices_begin(); +All_vertices_iterator all_vertices_begin() const; /*! Past-the-end iterator. */ -All_vertices_iterator all_vertices_end(); +All_vertices_iterator all_vertices_end() const; /*! Starts at an arbitrary edge. */ -All_edges_iterator all_edges_begin(); +All_edges_iterator all_edges_begin() const; /*! Past-the-end iterator. */ -All_edges_iterator all_edges_end(); +All_edges_iterator all_edges_end() const; /*! Starts at an arbitrary face. */ -All_faces_iterator all_faces_begin(); +All_faces_iterator all_faces_begin() const; /*! Past-the-end iterator. */ -All_faces_iterator all_faces_end(); +All_faces_iterator all_faces_end() const; /// @} @@ -405,22 +414,22 @@ All_faces_iterator all_faces_end(); /*! Starts at an arbitrary input site. */ -Input_sites_iterator input_sites_begin(); +Input_sites_iterator input_sites_begin() const; /*! Past-the-end iterator. */ -Input_sites_iterator input_sites_end(); +Input_sites_iterator input_sites_end() const; /*! Starts at an arbitrary output site. */ -Output_sites_iterator output_sites_begin(); +Output_sites_iterator output_sites_begin() const; /*! Past-the-end iterator. */ -Output_sites_iterator output_sites_end(); +Output_sites_iterator output_sites_end() const; /// @} @@ -450,39 +459,39 @@ Output_sites_iterator output_sites_end(); Starts at an arbitrary face incident to `v`. */ -Face_circulator incident_faces(Vertex_handle v); +Face_circulator incident_faces(Vertex_handle v) const; /*! Starts at face `f`. \pre Face `f` is incident to vertex `v`. */ -Face_circulator incident_faces(Vertex_handle v, Face_handle f); +Face_circulator incident_faces(Vertex_handle v, Face_handle f) const; /*! Starts at an arbitrary edge incident to `v`. */ -Edge_circulator incident_edges(Vertex_handle v); +Edge_circulator incident_edges(Vertex_handle v) const; /*! Starts at the first edge of `f` incident to `v`, in counterclockwise order around `v`. \pre Face `f` is incident to vertex `v`. */ -Edge_circulator incident_edges(Vertex_handle v, Face_handle f); +Edge_circulator incident_edges(Vertex_handle v, Face_handle f) const; /*! Starts at an arbitrary vertex incident to `v`. */ -Vertex_circulator incident_vertices(Vertex_handle v); +Vertex_circulator incident_vertices(Vertex_handle v) const; /*! Starts at the first vertex of `f` adjacent to `v` in counterclockwise order around `v`. \pre Face `f` is incident to vertex `v`. */ -Vertex_circulator incident_vertices(Vertex_handle v, Face_handle f); +Vertex_circulator incident_vertices(Vertex_handle v, Face_handle f) const; /// @} @@ -522,41 +531,38 @@ bool is_infinite(Edge_circulator ec) const; /// @{ /*! -Inserts the sites in the range -[`first`,`beyond`). The number of additional sites inserted in -the Delaunay graph is returned. `Input_iterator` must be a model of -`InputIterator` and its value type must be -either `Point_2` or `Site_2`. +Iteratively inserts the sites in the range [`first`,`beyond`). +\tparam Input_iterator must be a model of `InputIterator` and its value type must be either `Point_2` or `Site_2`. +\return the number of sites inserted in the Delaunay graph */ template< class Input_iterator > size_type insert(Input_iterator first, Input_iterator beyond); /*! -Same as the previous method. `Input_iterator` must be a model of -`InputIterator` and its value type must be -either `Point_2` or `Site_2`. +Iteratively inserts the sites in the range [`first`,`beyond`). +\tparam Input_iterator must be a model of `InputIterator` and its value type must be either `Point_2` or `Site_2`. +\return the number of sites inserted in the Delaunay graph */ template< class Input_iterator > -size_type insert(Input_iterator first, Input_iterator beyond, Tag_false); +size_type insert(Input_iterator first, Input_iterator beyond, CGAL::Tag_false); /*! Decomposes the range [first,beyond) into a range of input points and a range of input segments that are respectively passed to `insert_segments()` and `insert_points()`. Non-input sites are first random_shuffled and then inserted one by one. -`Input_iterator` must be a model of `InputIterator` and its value type must be -either `Point_2`, `Segment_2` or `Site_2`. -\return the number of sites inserted in the Delaunay graph +\tparam Input_iterator must be a model of `InputIterator` and its value type must be either `Point_2`, `Segment_2` or `Site_2`. +\return the number of sites inserted in the Delaunay graph */ template< class Input_iterator > -size_type insert(Input_iterator first, Input_iterator beyond, Tag_true); +size_type insert(Input_iterator first, Input_iterator beyond, CGAL::Tag_true); /*! Inserts the points in the range [first,beyond) as sites. Note that this function is not guaranteed to insert the points following the order of `PointInputIterator`, as `spatial_sort()` is used to improve efficiency. -\return the number of points inserted in the Delaunay graph \tparam PointIterator must be an input iterator `Point_2` or `Site_2` as value_type. +\return the number of points inserted in the Delaunay graph */ template std::size_t insert_points(PointIterator first, PointIterator beyond); @@ -566,8 +572,8 @@ Inserts the segments in the range [first,beyond) as sites. Note that this function is not guaranteed to insert the segments following the order of `SegmentIterator`, as `spatial_sort()` is used to improve efficiency. -\return the number of segments inserted in the Delaunay graph \tparam SegmentIterator must be an input iterator with `Site_2`, `Segment_2` or `std::pair` as value type. +\return the number of segments inserted in the Delaunay graph */ template std::size_t insert_segments(SegmentIterator first, SegmentIterator beyond); @@ -577,33 +583,30 @@ Same as above except that each segment is given as a pair of indices of the poin in the range [points_first, points_beyond). The indices must start from 0 to `std::distance(points_first, points_beyond)` \tparam PointIterator is an input iterator with `Point_2` as value type. \tparam IndicesIterator is an input iterator with `std::pair` as value type. +\return the number of segments inserted in the Delaunay graph */ template std::size_t insert_segments(PointIterator points_first, PointIterator points_beyond, IndicesIterator indices_first, IndicesIterator indices_beyond); /*! -Inserts the -point `p` in the segment Delaunay graph. If `p` has already -been inserted, then the vertex handle of its already inserted copy is -returned. If `p` has not been inserted yet, the vertex handle of -`p` is returned. +Inserts the point `p` in the segment Delaunay graph. +If `p` has already been inserted, then the vertex handle of its already inserted copy is returned. +If `p` has not been inserted yet, the vertex handle of `p` is returned. */ -Vertex_handle insert(Point_2 p); +Vertex_handle insert(const Point_2& p); /*! -Inserts `p` in the segment Delaunay graph using the site -associated with `vnear` as an estimate for the nearest neighbor -of `p`. The vertex handle returned has the same semantics as -the vertex handle returned by the method +Inserts `p` in the segment Delaunay graph using the site associated with `vnear` +as an estimate for the nearest neighbor of `p`. +The vertex handle returned has the same semantics as the vertex handle returned by the method `Vertex_handle insert(Point_2 p)`. */ -Vertex_handle insert(Point_2 p, Vertex_handle vnear); +Vertex_handle insert(const Point_2& p, Vertex_handle vnear); /*! -Inserts the -closed segment with endpoints `p1` and `p2` in the segment -Delaunay graph. If the segment has already been inserted in the +Inserts the closed segment with endpoints `p1` and `p2` in the segment Delaunay graph. +If the segment has already been inserted in the Delaunay graph then the vertex handle of its already inserted copy is returned. If the segment does not intersect any segment in the existing diagram, the vertex handle corresponding to its @@ -611,40 +614,34 @@ corresponding open segment is returned. Finally, if the segment intersects other segments in the existing Delaunay graph, the vertex handle to one of its open subsegments is returned. */ -Vertex_handle insert(Point_2 p1, Point_2 p2); +Vertex_handle insert(const Point_2& p1, const Point_2& p2); /*! -Inserts the segment whose endpoints are `p1` and `p2` -in the segment Delaunay graph using the site -associated with `vnear` as an estimate for the nearest neighbor -of `p1`. The vertex handle returned has the same semantics as the -vertex handle returned by the method +Inserts the segment whose endpoints are `p1` and `p2` in the segment Delaunay graph using the site +associated with `vnear` as an estimate for the nearest neighbor of `p1`. +The vertex handle returned has the same semantics as the vertex handle returned by the method `Vertex_handle insert(Point_2 p1, Point_2 p2)`. */ -Vertex_handle insert(Point_2 p1, Point_2 p2, Vertex_handle -vnear); +Vertex_handle insert(const Point_2& p1, const Point_2& p2, Vertex_handle vnear); /*! -Inserts the site `s` in the -segment Delaunay graph. The vertex handle returned has the same -semantics as the vertex handle returned by the methods -`Vertex_handle insert(Point_2 p)` and `Vertex_handle insert(Point_2 p1, Point_2 p2)`, depending on whether `s` -represents a point or a segment respectively. +Inserts the site `s` in the segment Delaunay graph. +The vertex handle returned has the same semantics as the vertex handle returned by the methods +`Vertex_handle insert(Point_2 p)` and `Vertex_handle insert(Point_2 p1, Point_2 p2)`, +depending on whether `s` represents a point or a segment respectively. \pre `s.is_input()` must be `true`. */ -Vertex_handle insert(Site_2 s); +Vertex_handle insert(const Site_2& s); /*! -Inserts `s` in the segment Delaunay graph using the site -associated with `vnear` as an estimate for the nearest neighbor of -`s`, if `s` is a point, or the first endpoint of `s`, if -`s` is a segment. The vertex handle returned has the same -semantics as the vertex handle returned by the method +Inserts `s` in the segment Delaunay graph using the site associated with `vnear` +as an estimate for the nearest neighbor of `s`, if `s` is a point, or the first endpoint of `s`, if +`s` is a segment. +The vertex handle returned has the same semantics as the vertex handle returned by the method `Vertex_handle insert(Site_2 s)`. \pre `s.is_input()` must be `true`. */ -Vertex_handle insert(Site_2 s, Vertex_handle -vnear); +Vertex_handle insert(const Site_2& s, Vertex_handle vnear); /// @} @@ -658,7 +655,7 @@ finds the site whose segment Voronoi diagram cell contains of `p` is returned. If there are no sites in the segment Delaunay graph `Vertex_handle()` is returned. */ -Vertex_handle nearest_neighbor(Point_2 p); +Vertex_handle nearest_neighbor(const Point_2& p) const; /*! Finds the nearest neighbor of the point @@ -668,8 +665,7 @@ arbitrarily and one of the nearest neighbors of `p` is returned. If there are no sites in the segment Delaunay graph `Vertex_handle()` is returned. */ -Vertex_handle nearest_neighbor(Point_2 p, -Vertex_handle vnear); +Vertex_handle nearest_neighbor(const Point_2& p, Vertex_handle vnear) const; /// @} @@ -689,7 +685,7 @@ defined: */ template < class Stream > -Stream& draw_dual(Stream& str); +Stream& draw_dual(Stream& str) const; /*! Draws the segment Voronoi @@ -705,7 +701,7 @@ The following operators must be defined: */ template < class Stream > -Stream& draw_skeleton(Stream& str); +Stream& draw_skeleton(Stream& str) const; /*! Draws the edge `e` of @@ -720,7 +716,7 @@ The following operators must be defined: \pre `e` must be a finite edge. */ template< class Stream > -Stream& draw_dual_edge(Edge e, Stream& str); +Stream& draw_dual_edge(Edge e, Stream& str) const; /*! Draws the edge `*ec` of the segment Voronoi diagram to the stream @@ -735,7 +731,7 @@ The following operators must be defined: \pre `*ec` must be a finite edge. */ template< class Stream > -Stream& draw_dual_edge(Edge_circulator ec, Stream& str); +Stream& draw_dual_edge(Edge_circulator ec, Stream& str) const; /*! Draws the edge `*eit` of the segment Voronoi diagram to the @@ -750,7 +746,7 @@ The following operators must be defined: \pre `*eit` must be a finite edge. */ template< class Stream > -Stream& draw_dual_edge(All_edges_iterator eit, Stream& str); +Stream& draw_dual_edge(All_edges_iterator eit, Stream& str) const; /*! Draws the edge `*eit` of the segment Voronoi diagram to the @@ -764,7 +760,7 @@ The following operators must be defined: `Stream& operator<<(Stream&, Gt::Line_2)` */ template< class Stream > -Stream& draw_dual_edge(Finite_edges_iterator eit, Stream& str); +Stream& draw_dual_edge(Finite_edges_iterator eit, Stream& str) const; /*! Writes the current @@ -776,20 +772,19 @@ combinatorial data structure. void file_output(std::ostream& os); /*! -Reads the state of the -segment Delaunay graph from an input stream. +Reads the state of the segment Delaunay graph from an input stream. */ void file_input(std::istream& is); /*! Writes the current state of the segment Delaunay graph to an output stream. */ -std::ostream& operator<<(std::ostream& os, Segment_Delaunay_graph_2 sdg); +std::ostream& operator<<(std::ostream& os, const Segment_Delaunay_graph_2& sdg); /*! Reads the state of the segment Delaunay graph from an input stream. */ -std::istream& operator>>(std::istream& is, Segment_Delaunay_graph_2 sdg); +std::istream& operator>>(std::istream& is, Segment_Delaunay_graph_2& sdg); /// @} @@ -805,7 +800,7 @@ Delaunay graph are validated. Negative values of `level` always return true, and values greater than 1 are equivalent to `level` being 1. */ -bool is_valid(bool verbose = false, int level = 1); +bool is_valid(bool verbose = false, int level = 1) const; /// @} @@ -818,13 +813,12 @@ Clears all contents of the segment Delaunay graph. void clear(); /*! -The segment Delaunay graphs -`other` and `*this` are swapped. For a segment Delaunay graph `sdg`, the operation +The segment Delaunay graphs `other` and `*this` are swapped. +For a segment Delaunay graph `sdg`, the operation `sdg`.`swap(other)` should be preferred to `sdg``= other` or to `sdg``(other)` if `other` is deleted afterwards. */ -void swap(Segment_Delaunay_graph_2 -other); +void swap(Segment_Delaunay_graph_2& other); /// @} diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_face_base_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_face_base_2.h new file mode 100644 index 00000000000..69fc93cf421 --- /dev/null +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_face_base_2.h @@ -0,0 +1,27 @@ + +namespace CGAL { + +/*! +\ingroup PkgSegmentDelaunayGraph2Ref + +\cgalModels `SegmentDelaunayGraphFaceBase_2` + +The class `Segment_Delaunay_graph_face_base_2` provides a model for the +`SegmentDelaunayGraphFaceBase_2` concept which is the face +base required by the `SegmentDelaunayGraphDataStructure_2` +concept. + +\tparam Gt must be a model of the concept `SegmentDelaunayGraphTraits_2`. + This type must be identical to the template parameter used for `CGAL::Segment_Delaunay_graph_2`. + +\tparam Fb is a face base class from which `Segment_Delaunay_graph_face_base_2` derives. + It must be a model of the `TriangulationFaceBase_2` concept. + It has the default value `CGAL::Triangulation_face_base_2`. +*/ +template< typename Gt, typename Fb > +class Segment_Delaunay_graph_face_base_2 { +public: + +}; /* end Segment_Delaunay_graph_face_base_2 */ + +} /* end namespace CGAL */ diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_filtered_traits_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_filtered_traits_2.h index 214ca7577bc..00be59b9a75 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_filtered_traits_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_filtered_traits_2.h @@ -8,7 +8,7 @@ The class `Segment_Delaunay_graph_filtered_traits_2` provides a model for the `SegmentDelaunayGraphTraits_2` concept. The class `Segment_Delaunay_graph_filtered_traits_2` uses the filtering technique \cgalCite{cgal:bbp-iayed-01} -to achieve traits for the `Segment_Delaunay_graph_2` +to achieve traits for the `Segment_Delaunay_graph_2` class with efficient and exact predicates given an exact kernel `EK` and a filtering kernel `FK`. The geometric constructions associated provided by this class are equivalent @@ -50,7 +50,7 @@ The default values for the template parameters are as follows:
  • `EM = Field_tag`,
  • `FK = Simple_cartesian >`,
  • `FM = Field_with_sqrt_tag`. -
  • If the \sc{Gmp} package is installed with \cgal, the template parameter `EK` has the default value: `EK = Simple_cartesian`, otherwise its default value is `EK = Simple_cartesian >`. +
  • If the \gmp package is installed with \cgal, the template parameter `EK` has the default value: `EK = Simple_cartesian`, otherwise its default value is `EK = Simple_cartesian >`. \cgalModels `SegmentDelaunayGraphTraits_2` @@ -58,12 +58,11 @@ The default values for the template parameters are as follows: \cgalModels `CopyConstructible` \cgalModels `Assignable` -\sa `Kernel` \sa `SegmentDelaunayGraphTraits_2` \sa `CGAL::Field_tag` \sa `CGAL::Field_with_sqrt_tag` -\sa `CGAL::Segment_Delaunay_graph_2` -\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` +\sa `CGAL::Segment_Delaunay_graph_2` +\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` \sa `CGAL::Segment_Delaunay_graph_traits_2` \sa `CGAL::Segment_Delaunay_graph_traits_without_intersections_2` \sa `CGAL::Segment_Delaunay_graph_filtered_traits_without_intersections_2` @@ -156,7 +155,7 @@ The class `Segment_Delaunay_graph_filtered_traits_without_intersections_2` provi `SegmentDelaunayGraphTraits_2` concept. The class `Segment_Delaunay_graph_filtered_traits_without_intersections_2` uses the filtering technique \cgalCite{cgal:bbp-iayed-01} -to achieve traits for the `Segment_Delaunay_graph_2` +to achieve traits for the `Segment_Delaunay_graph_2` class with efficient and exact predicates given an exact kernel `EK` and a filtering kernel `FK`. The geometric constructions associated provided by this class are equivalent @@ -205,7 +204,7 @@ will be the entry for the template parameter `CK`),
  • `EM = CGAL::Euclidean_ring_tag`,
  • `FK = CGAL::Simple_cartesian >`,
  • `FM = CGAL::Field_with_sqrt_tag`. -
  • If the \sc{Gmp} package is +
  • If the \gmp package is installed with \cgal, the template parameter `EK` has the default value: `EK = CGAL::Simple_cartesian`, otherwise its default value is @@ -221,8 +220,8 @@ default value is \sa `SegmentDelaunayGraphTraits_2` \sa `CGAL::Euclidean_ring_tag` \sa `CGAL::Field_with_sqrt_tag` -\sa `CGAL::Segment_Delaunay_graph_2` -\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` +\sa `CGAL::Segment_Delaunay_graph_2` +\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` \sa `CGAL::Segment_Delaunay_graph_traits_2` \sa `CGAL::Segment_Delaunay_graph_traits_without_intersections_2` \sa `CGAL::Segment_Delaunay_graph_filtered_traits_2` diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_hierarchy_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_hierarchy_2.h index 49b75205b61..450a299f188 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_hierarchy_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_hierarchy_2.h @@ -5,8 +5,9 @@ namespace CGAL { \ingroup PkgSegmentDelaunayGraph2Ref We provide an alternative to the class -`Segment_Delaunay_graph_2` for the incremental -construction of the segment Delaunay graph. The `Segment_Delaunay_graph_hierarchy_2` class +`Segment_Delaunay_graph_2` for the incremental +construction of the segment Delaunay graph. +The `Segment_Delaunay_graph_hierarchy_2` class maintains a hierarchy of Delaunay graphs. There are two possibilities as to how this hierarchy is constructed. @@ -21,44 +22,49 @@ In the second case the upper levels of the hierarchy contains not only points but also segments. A site that is in level \f$ i\f$, is in level \f$ i+1\f$ with probability \f$ 1/\beta\f$ where \f$ \beta > 1\f$ is some constant. -The difference between the `Segment_Delaunay_graph_2` +The difference between the `Segment_Delaunay_graph_2` class and the `Segment_Delaunay_graph_hierarchy_2` class (both versions of it) is on how the nearest neighbor location is done. Given a point \f$ p\f$ the location is done as follows: at the top most level we find the nearest neighbor of -\f$ p\f$ as in the `Segment_Delaunay_graph_2` class. At +\f$ p\f$ as in the `Segment_Delaunay_graph_2` class. At every subsequent level \f$ i\f$ we use the nearest neighbor found at level \f$ i+1\f$ to find the nearest neighbor at level \f$ i\f$. This is a variant of the corresponding hierarchy for points found in \cgalCite{cgal:d-dh-02}. The details are described in \cgalCite{cgal:k-reisv-04}. -The class has three template parameters. The first and third -have essentially the same semantics as in the -`Segment_Delaunay_graph_2` class. +The class has four template parameters. The first and fourth +have essentially the same semantics as in the `Segment_Delaunay_graph_2` class. \tparam Gt must be a model of the `SegmentDelaunayGraphTraits_2` concept. -\tparam STag The second template +\tparam St must be a model of `SegmentDelaunayGraphStorageTraits_2`. + By default, the storage traits is instantiated by `Segment_Delaunay_graph_storage_traits_2`. + +\tparam STag The third template parameter controls whether or not segments are added in the upper levels of the hierarchy. It's possible values are `Tag_true` and `Tag_false`. If it is set to `Tag_true`, segments are also inserted in the upper levels of the hierarchy. The value `Tag_false` indicates that only points are to be inserted in the upper levels of the hierarchy. The default value for -the second template parameter is `Tag_false`. +the third template parameter is `Tag_false`. \tparam DS must be a model of the `SegmentDelaunayGraphDataStructure_2` concept. However, the vertex base class that is to be used in the segment Delaunay graph data structure must be a model of the `SegmentDelaunayGraphHierarchyVertexBase_2` -concept. The third template parameter defaults to -`Triangulation_data_structure_2< Segment_Delaunay_graph_hierarchy_vertex_base_2< Segment_Delaunay_graph_vertex_base_2 >, Triangulation_face_base_2 >`. - - +concept. The fourth template parameter defaults to: +\code +`CGAL::Triangulation_data_structure_2< + CGAL::Segment_Delaunay_graph_hierarchy_vertex_base_2< + CGAL::Segment_Delaunay_graph_vertex_base_2, + CGAL::Segment_Delaunay_graph_face_base_2 >` +\endcode The `Segment_Delaunay_graph_hierarchy_2` class derives publicly from the -`Segment_Delaunay_graph_2` class. The interface is +`Segment_Delaunay_graph_2` class. The interface is the same with its base class. In the sequel only additional types and methods defined are documented. @@ -66,10 +72,7 @@ and methods defined are documented. \cgalModels `CopyConstructible` \cgalModels `Assignable` -\sa `SegmentDelaunayGraphDataStructure_2` -\sa `SegmentDelaunayGraphTraits_2` -\sa `SegmentDelaunayGraphHierarchyVertexBase_2` -\sa `CGAL::Segment_Delaunay_graph_2` +\sa `CGAL::Segment_Delaunay_graph_2` \sa `CGAL::Triangulation_data_structure_2` \sa `CGAL::Segment_Delaunay_graph_traits_2` \sa `CGAL::Segment_Delaunay_graph_traits_without_intersections_2` @@ -78,14 +81,15 @@ and methods defined are documented. \sa `CGAL::Segment_Delaunay_graph_hierarchy_vertex_base_2` */ -template< typename Gt, typename STag, typename DS > -class Segment_Delaunay_graph_hierarchy_2 : public CGAL::Segment_Delaunay_graph_2 { +template< typename Gt, typename St, typename STag, typename DS > +class Segment_Delaunay_graph_hierarchy_2 + : public CGAL::Segment_Delaunay_graph_2 { public: /// \name Types /// `Segment_Delaunay_graph_hierarchy_2` introduces the following /// types in addition to those introduced by its base class -/// `Segment_Delaunay_graph_2`. +/// `Segment_Delaunay_graph_2`. /// @{ /*! @@ -97,7 +101,7 @@ typedef STag Segments_in_hierarchy_tag; /*! A type for the base class. */ -typedef CGAL::Segment_Delaunay_graph_2 Base; +typedef CGAL::Segment_Delaunay_graph_2 Base; /// @} @@ -110,8 +114,7 @@ typedef CGAL::Segment_Delaunay_graph_2 Base; Creates a hierarchy of segment Delaunay graphs using `gt` as geometric traits. */ -Segment_Delaunay_graph_hierarchy_2(Gt -gt=Gt()); +Segment_Delaunay_graph_hierarchy_2(Gt gt=Gt()); /*! Creates a segment Delaunay graph hierarchy using @@ -121,9 +124,7 @@ model of `InputIterator`. The value type of `Input_iterator` must be either `Point_2` or `Site_2`. */ template< class Input_iterator > -Segment_Delaunay_graph_hierarchy_2(Input_iterator -first, Input_iterator beyond, Gt gt=Gt()); - +Segment_Delaunay_graph_hierarchy_2(Input_iterator first, Input_iterator beyond, Gt gt=Gt()); /// @} @@ -136,13 +137,13 @@ written to the stream (represented through appropriate input sites), as well as the underlying combinatorial hierarchical data structure. \relates Segment_Delaunay_graph_hierarchy_2 */ -std::ostream& operator<<(std::ostream& os, Segment_Delaunay_graph_hierarchy_2 svdh); +std::ostream& operator<<(std::ostream& os, const Segment_Delaunay_graph_hierarchy_2& svdh); /*! Reads the state of the segment Delaunay graph hierarchy from an input stream. \relates Segment_Delaunay_graph_hierarchy_2 */ -std::istream& operator>>(std::istream& is, Segment_Delaunay_graph_hierarchy_2 svdh); +std::istream& operator>>(std::istream& is, const Segment_Delaunay_graph_hierarchy_2& svdh); } /* end namespace CGAL */ diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_hierarchy_vertex_base_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_hierarchy_vertex_base_2.h index 56005dcd9d7..5ac99ae6de2 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_hierarchy_vertex_base_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_hierarchy_vertex_base_2.h @@ -7,7 +7,7 @@ namespace CGAL { The class `Segment_Delaunay_graph_hierarchy_vertex_base_2` provides a model for the `SegmentDelaunayGraphHierarchyVertexBase_2` concept, which is the vertex base required by the -`Segment_Delaunay_graph_hierarchy_2` class. +`Segment_Delaunay_graph_hierarchy_2` class. \tparam Vbb must be a model of the `SegmentDelaunayGraphVertexBase_2` concept. @@ -16,9 +16,9 @@ vertex base required by the \sa `SegmentDelaunayGraphVertexBase_2` \sa `SegmentDelaunayGraphHierarchyVertexBase_2` \sa `SegmentDelaunayGraphDataStructure_2` -\sa `CGAL::Segment_Delaunay_graph_vertex_base_2` +\sa `CGAL::Segment_Delaunay_graph_vertex_base_2` \sa `CGAL::Triangulation_data_structure_2` -\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` +\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` */ template< typename Vbb > diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_site_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_site_2.h index 8d11eb97bdd..596717be5cc 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_site_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_site_2.h @@ -7,20 +7,13 @@ namespace CGAL { The class `Segment_Delaunay_graph_storage_site_2` is a model for the concept `SegmentDelaunayGraphStorageSite_2`. -\tparam Gt must be a model of the `SegmentDelaunayGraphTraits_2` concept. +\tparam Gt must be a model of the `SegmentDelaunayGraphStorageTraits_2` concept. \cgalModels `SegmentDelaunayGraphStorageSite_2` -\sa `SegmentDelaunayGraphSite_2` -\sa `SegmentDelaunayGraphTraits_2` \sa `CGAL::Segment_Delaunay_graph_site_2` -\sa `CGAL::Segment_Delaunay_graph_traits_2` -\sa `CGAL::Segment_Delaunay_graph_traits_without_intersections_2` -\sa `CGAL::Segment_Delaunay_graph_filtered_traits_2` -\sa `CGAL::Segment_Delaunay_graph_filtered_traits_without_intersections_2` - */ -template< typename Gt > +template< typename St > class Segment_Delaunay_graph_storage_site_2 { public: @@ -31,9 +24,9 @@ public: /// @{ /*! -A type for the template parameter `Gt`. +A type for the template parameter `St`. */ -typedef Gt Geom_traits; +typedef St Storage_traits; /// @} diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_site_with_info_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_site_with_info_2.h new file mode 100644 index 00000000000..fc8180ff3d8 --- /dev/null +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_site_with_info_2.h @@ -0,0 +1,50 @@ + +namespace CGAL { + +/*! +\ingroup PkgSegmentDelaunayGraph2Ref + +The class `Segment_Delaunay_graph_storage_site_with_info_2` is a model for the concept +`SegmentDelaunayGraphStorageSite_2`. + +\tparam STraits must be a model of the `SegmentDelaunayGraphStorageTraits_2` concept. +\tparam Base must be a model of `SegmentDelaunayGraphStorageSite_2` + +\cgalModels `SegmentDelaunayGraphStorageSite_2` + +\sa `CGAL::Segment_Delaunay_graph_site_2` +*/ +template< typename STraits, typename Info_, typename Base > +class Segment_Delaunay_graph_storage_site_with_info_2 : public Base { +public: + + /// \name Types + /// The class + /// @{ + + typedef STraits Storage_traits; + /*! + */ + typedef Info_ Info; + + typedef typename Storage_traits::Geom_traits Geom_traits; + typedef typename Geom_traits::Site_2 Site_2; + typedef typename Storage_traits::Point_handle Point_handle; + + struct Has_info_tag {}; + /// @} + + /*! + */ + const Info& info() const; + + /*! + */ + void set_info(const Info&) const; + + /*! + */ + bool info_has_been_set() const; + +}; /* end Segment_Delaunay_graph_storage_site_with_info_2 */ +} /* end namespace CGAL */ diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_traits_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_traits_2.h new file mode 100644 index 00000000000..8fb333abcc0 --- /dev/null +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_traits_2.h @@ -0,0 +1,34 @@ +namespace CGAL { + +/*! +\ingroup PkgSegmentDelaunayGraph2Ref + +The class `Segment_Delaunay_graph_storage_traits_2` provides a model for the +`SegmentDelaunayGraphStorageTraits_2` concept. + +To avoid redundancy in the storage of points, the input points of a segment Delaunay graph +are stored in a container, and the various types of sites (input points and segments, +points of intersection, subsegments with one or two points of intersection as endpoints) +only store handles to the points in the container. + +See section \ref Segment_Delaunay_graph_2StronglyIntersecting for more information. + +\tparam Gt must be a model of the concept `SegmentDelaunayGraphTraits_2`. + +\cgalModels `SegmentDelaunayGraphStorageTraits_2` + +\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` +\sa `CGAL::Segment_Delaunay_graph_traits_without_intersections_2` +\sa `CGAL::Segment_Delaunay_graph_filtered_traits_2` +\sa `CGAL::Segment_Delaunay_graph_filtered_traits_without_intersections_2` +*/ +template +class Segment_Delaunay_graph_storage_traits_2 +{ +public: + /*! + */ + typedef unspecified_type Storage_site_2; +}; + +} //namespace CGAL diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_traits_with_info_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_traits_with_info_2.h new file mode 100644 index 00000000000..eb032cea795 --- /dev/null +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_storage_traits_with_info_2.h @@ -0,0 +1,35 @@ +namespace CGAL { + +/*! +\ingroup PkgSegmentDelaunayGraph2Ref + +The class `Segment_Delaunay_graph_storage_traits_with_info_2` provides a model for the +`SegmentDelaunayGraphStorageTraits_2` concept. + + +\tparam Gt must be a model of the concept `SegmentDelaunayGraphTraits_2`. + +\cgalModels `SegmentDelaunayGraphStorageTraits_2` + +\sa `CGAL::`Segment_Delaunay_graph_storage_site_with_info_2` +*/ + template +class Segment_Delaunay_graph_storage_traits_with_info_2 + : public Segment_Delaunay_graph_storage_traits_2 +{ +public: + /*! + */ + typedef Info_ Info; + typedef Converter Convert_info; + typedef Merger Merge_info; + typedef typename Base::Geom_traits Geom_traits; + + typedef + Segment_Delaunay_graph_storage_site_with_info_2 Storage_site_2; + +}; + +} //namespace CGAL diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_traits_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_traits_2.h index c27eef36376..1dead711c35 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_traits_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_traits_2.h @@ -28,8 +28,8 @@ part). \sa `SegmentDelaunayGraphTraits_2` \sa `CGAL::Field_tag` \sa `CGAL::Field_with_sqrt_tag` -\sa `CGAL::Segment_Delaunay_graph_2` -\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` +\sa `CGAL::Segment_Delaunay_graph_2` +\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` \sa `CGAL::Segment_Delaunay_graph_traits_without_intersections_2` \sa `CGAL::Segment_Delaunay_graph_filtered_traits_2` \sa `CGAL::Segment_Delaunay_graph_filtered_traits_without_intersections_2` @@ -101,8 +101,8 @@ part). \sa `SegmentDelaunayGraphTraits_2` \sa `CGAL::Euclidean_ring_tag` \sa `CGAL::Field_with_sqrt_tag` -\sa `CGAL::Segment_Delaunay_graph_2` -\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` +\sa `CGAL::Segment_Delaunay_graph_2` +\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` \sa `CGAL::Segment_Delaunay_graph_traits_2` \sa `CGAL::Segment_Delaunay_graph_filtered_traits_2` \sa `CGAL::Segment_Delaunay_graph_filtered_traits_without_intersections_2` diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_vertex_base_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_vertex_base_2.h index ed3e1069c1e..b925fa57dd9 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_vertex_base_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/CGAL/Segment_Delaunay_graph_vertex_base_2.h @@ -4,33 +4,23 @@ namespace CGAL { /*! \ingroup PkgSegmentDelaunayGraph2Ref +\cgalModels `SegmentDelaunayGraphVertexBase_2` + The class `Segment_Delaunay_graph_vertex_base_2` provides a model for the `SegmentDelaunayGraphVertexBase_2` concept which is the vertex base required by the `SegmentDelaunayGraphDataStructure_2` concept. -\tparam Gt must be a model of the concept `SegmentDelaunayGraphTraits_2`. -\tparam SSTag indicates whether -or not to use the simple storage site that does not support -intersecting segments, or the full storage site, that supports -intersecting segments. The possible values are `Tag_true` -and `Tag_false`. `Tag_true` indicates that the -full storage site is to be used, whereas `Tag_false` -indicates that the simple storage site is to be used. +\tparam St must be a model of the concept `SegmentDelaunayGraphStorageTraits_2`. + This type must be template parameter used for `CGAL::Segment_Delaunay_graph_2`. -\cgalModels `SegmentDelaunayGraphVertexBase_2` - -\sa `SegmentDelaunayGraphVertexBase_2` -\sa `SegmentDelaunayGraphDataStructure_2` -\sa `SegmentDelaunayGraphTraits_2` -\sa `CGAL::Triangulation_data_structure_2` -\sa `CGAL::Segment_Delaunay_graph_traits_2` -\sa `CGAL::Segment_Delaunay_graph_traits_without_intersections_2` -\sa `CGAL::Segment_Delaunay_graph_filtered_traits_2` -\sa `CGAL::Segment_Delaunay_graph_filtered_traits_without_intersections_2` +\tparam Vb is a vertex base class from which `Segment_Delaunay_graph_vertex_base_2` derives. + It must be a model of the `TriangulationDSVertexBase_2` concept. + It has the default value `CGAL::Triangulation_ds_vertex_base_2<>`. +\sa `CGAL::Segment_Delaunay_graph_hierarchy_vertex_base_2` */ -template< typename Gt, typename SSTag > +template< typename St, typename Vb > class Segment_Delaunay_graph_vertex_base_2 { public: diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphFaceBase_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphFaceBase_2.h new file mode 100644 index 00000000000..8837bc14b74 --- /dev/null +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphFaceBase_2.h @@ -0,0 +1,22 @@ + +/*! +\ingroup PkgSegmentDelaunayGraph2Concepts +\cgalConcept + +The concept `SegmentDelaunayGraphFaceBase_2` describes the +requirements for the face base class of the +`SegmentDelaunayGraphDataStructure_2` concept. + +\cgalRefines `TriangulationFaceBase_2` + +\cgalHasModel `CGAL::Segment_Delaunay_graph_face_base_2` + +\sa `SegmentDelaunayGraphDataStructure_2` +\sa `SegmentDelaunayGraphTraits_2` +\sa `CGAL::Triangulation_data_structure_2` +*/ +class SegmentDelaunayGraphFaceBase_2 { +public: + +}; /* end SegmentDelaunayGraphFaceBase_2 */ + diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphHierarchyVertexBase_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphHierarchyVertexBase_2.h index e55017d68e7..626239edae2 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphHierarchyVertexBase_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphHierarchyVertexBase_2.h @@ -26,13 +26,13 @@ The `SegmentDelaunayGraphHierarchyVertexBase_2` concept does not introduce any constructors in addition to those of the `SegmentDelaunayGraphVertexBase_2` concept. -\cgalHasModel CGAL::Segment_Delaunay_graph_hierarchy_vertex_base_2 > +\cgalHasModel CGAL::Segment_Delaunay_graph_hierarchy_vertex_base_2 > \sa `SegmentDelaunayGraphDataStructure_2` \sa `SegmentDelaunayGraphVertexBase_2` -\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` +\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` \sa `CGAL::Triangulation_data_structure_2` -\sa `CGAL::Segment_Delaunay_graph_vertex_base_2` +\sa `CGAL::Segment_Delaunay_graph_vertex_base_2` \sa `CGAL::Segment_Delaunay_graph_hierarchy_vertex_base_2` */ diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphSite_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphSite_2.h index e6dbd01f666..d52818a7e70 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphSite_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphSite_2.h @@ -51,7 +51,7 @@ typedef unspecified_type RT; /// \name Creation /// In addition to the default and copy constructors the following -/// static methods are available for constructing sites: +/// static methods must be available for constructing sites: /// @{ /*! diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphStorageTraits_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphStorageTraits_2.h new file mode 100644 index 00000000000..63d1ae08db2 --- /dev/null +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphStorageTraits_2.h @@ -0,0 +1,92 @@ + +/*! +\ingroup PkgSegmentDelaunayGraph2Concepts +\cgalConcept + +The concept `SegmentDelaunayGraphStorageTraits_2` provides the +requirements for the storage traits of a segment Delaunay graph. + +To avoid redundancy in the storage of points, the input points of a segment Delaunay graph +are stored in a container, and the various types of sites (input points and segments, +points of intersection, subsegments with one or two points of intersection as endpoints) +only store handles to the points in the container. + +See section \ref Segment_Delaunay_graph_2StronglyIntersecting for more information. + +\cgalRefines `DefaultConstructible` +\cgalRefines `CopyConstructible` +\cgalRefines `Assignable` + +\cgalHasModel `CGAL::Segment_Delaunay_graph_storage_traits_2` + +\sa `SegmentDelaunayGraphTraits_2` +*/ + +class SegmentDelaunayGraphStorageTraits_2 { +public: + +/// \name Types +/// @{ + + /*! + The geometric traits type. It must be a model of `SegmentDelaunayGraphTraits_2`. + */ + typedef unspecified_type Geom_traits; + + /*! + A container of unique points, used to associate a unique handle to each + unique input geometric position. + */ + typedef std::set Point_container; + + /*! + */ + typedef Point_container::iterator Point_handle; + + /*! + */ + typedef Point_container::const_iterator const_Point_handle; + + /*! + Type for the storage site. It must be a model of `SegmentDelaunayGraphStorageSite_2`. + */ + typedef unspecified_type Storage_site_2; + + /*! + Type of the storage site construction functor. + */ + typedef CGAL::SegmentDelaunayGraph_2::Construct_storage_site_2 Construct_storage_site_2; + +/// @} + +/// \name Creation +/// @{ + + /*! + Constructor. + */ + SegmentDelaunayGraphStorageTraits_2(const Geom_traits& gt = Geom_traits()); + +/// @} + +/// \name Access Functions +/// @{ + + /*! + returns the geometric traits. + */ + const Geom_traits& geom_traits() const; + +/// @} + +/// \name Constructions +/// @{ + + /*! + returns a functor of type `Construct_storage_site_2`. + */ + Construct_storage_site_2 construct_storage_site_2_object() const +/// @} + +}; /* end SegmentDelaunayGraphStorageTraits_2 */ + diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphTraits_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphTraits_2.h index 240688dd27f..677d942fe8f 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphTraits_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphTraits_2.h @@ -1,14 +1,15 @@ /*! \ingroup PkgSegmentDelaunayGraph2Concepts + \cgalConcept \cgalRefines `TriangulationTraits_2` The concept `SegmentDelaunayGraphTraits_2` provides the traits -requirements for the `CGAL::Segment_Delaunay_graph_2` and -`CGAL::Segment_Delaunay_graph_hierarchy_2` classes. In -particular, it provides a type `Site_2`, which must be a model of +requirements for the `CGAL::Segment_Delaunay_graph_2` and +`CGAL::Segment_Delaunay_graph_hierarchy_2` classes. +In particular, it provides a type `Site_2`, which must be a model of the concept `SegmentDelaunayGraphSite_2`. It also provides constructions for sites and several function object types for the predicates. @@ -19,8 +20,8 @@ types for the predicates. \cgalHasModel `CGAL::Segment_Delaunay_graph_filtered_traits_without_intersections_2` \sa `SegmentDelaunayGraphSite_2` -\sa `CGAL::Segment_Delaunay_graph_2` -\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` +\sa `CGAL::Segment_Delaunay_graph_2` +\sa `CGAL::Segment_Delaunay_graph_hierarchy_2` \sa `CGAL::Segment_Delaunay_graph_traits_2` \sa `CGAL::Segment_Delaunay_graph_traits_without_intersections_2` \sa `CGAL::Segment_Delaunay_graph_filtered_traits_2` diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphVertexBase_2.h b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphVertexBase_2.h index 639b99e3b13..903d9e92b68 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphVertexBase_2.h +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Concepts/SegmentDelaunayGraphVertexBase_2.h @@ -3,7 +3,7 @@ \ingroup PkgSegmentDelaunayGraph2Concepts \cgalConcept -\cgalRefines `TriangulationVertexBase_2` +\cgalRefines `TriangulationDSVertexBase_2` The concept `SegmentDelaunayGraphVertexBase_2` describes the requirements for the vertex base class of the @@ -11,19 +11,15 @@ requirements for the vertex base class of the site of the segment Delaunay graph and provides access to one of its incident faces through a `Face_handle`. -\cgalHasModel `CGAL::Segment_Delaunay_graph_vertex_base_2` +\cgalHasModel `CGAL::Segment_Delaunay_graph_vertex_base_2` -\sa `SegmentDelaunayGraphDataStructure_2` \sa `SegmentDelaunayGraphTraits_2` \sa `SegmentDelaunayGraphSite_2` \sa `SegmentDelaunayGraphStorageSite_2` -\sa `CGAL::Segment_Delaunay_graph_vertex_base_2` \sa `CGAL::Segment_Delaunay_graph_site_2` \sa `CGAL::Segment_Delaunay_graph_storage_site_2` \sa `CGAL::Triangulation_data_structure_2` - */ - class SegmentDelaunayGraphVertexBase_2 { public: @@ -31,46 +27,40 @@ public: /// @{ /*! -A type for the geometric traits that defines -the site. \pre The type `Geom_traits` must define the type `Site_2`. +A type for the geometric traits that defines the site. +\pre The type `Geom_traits` must define the type `Site_2`. */ typedef unspecified_type Geom_traits; /*! -A type for the site. This type must coincide -with the type `Geom_traits::Site_2`. +A type for the site. This type must coincide with the type `Geom_traits::Site_2`. */ typedef unspecified_type Site_2; /*! -A type that indicates what kind of -storage type to use. `Storage_site_tag` must either be -`CGAL::Tag_true` or `CGAL::Tag_false`. +A type that indicates what kind of storage type to use. +`Storage_site_tag` must either be `CGAL::Tag_true` or `CGAL::Tag_false`. */ typedef unspecified_type Storage_site_tag; /*! -A type for the internal representation -of sites. This type must satisfy the requirements of the concept -`SegmentDelaunayGraphStorageSite_2`. +A type for the internal representation of sites. +This type must satisfy the requirements of the concept `SegmentDelaunayGraphStorageSite_2`. */ typedef unspecified_type Storage_site_2; /*! -A type for the -underlying data structure, to which the vertex belongs to. +A type for the underlying data structure, to which the vertex belongs to. */ typedef unspecified_type Data_structure; /*! -A type for the vertex handle of the -segment Delaunay graph data structure. +A type for the vertex handle of the segment Delaunay graph data structure. */ typedef unspecified_type Vertex_handle; /*! -A type for the face handle of the -segment Delaunay graph data structure. +A type for the face handle of the segment Delaunay graph data structure. */ typedef unspecified_type Face_handle; @@ -82,18 +72,15 @@ typedef unspecified_type Face_handle; /// @{ /*! -Constructs a vertex associated with the site represented by the -storage site `ss`. +Constructs a vertex associated with the site represented by the storage site `ss`. */ -SegmentDelaunayGraphVertexBase_2(Storage_site_2 ss); +SegmentDelaunayGraphVertexBase_2(const Storage_site_2& ss); /*! -Constructs a vertex associated with -the site represented by the storage site `ss`, +Constructs a vertex associated with the site represented by the storage site `ss`, and pointing to the face associated with the face handle `f`. */ -SegmentDelaunayGraphVertexBase_2(Storage_site_2 ss, -Face_handle f); +SegmentDelaunayGraphVertexBase_2(const Storage_site_2& ss, Face_handle f); /// @} @@ -103,7 +90,7 @@ Face_handle f); /*! Returns the storage site representing the site. */ -Storage_site_2 storage_site(); +const Storage_site_2& storage_site(); /*! Returns the site. @@ -123,7 +110,7 @@ Face_handle face(); /*! Sets the storage site. */ -void set_site(Storage_site_2 ss); +void set_site(const Storage_site_2& ss); /*! Sets the incident face. diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/PackageDescription.txt b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/PackageDescription.txt index 0c74e16e383..947f7034f0d 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/PackageDescription.txt +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/PackageDescription.txt @@ -20,7 +20,7 @@ \cgalPkgShortInfoEnd \cgalPkgDescriptionEnd -\cgal provides the class `CGAL::Segment_Delaunay_graph_2` for +\cgal provides the class `CGAL::Segment_Delaunay_graph_2` for computing the 2D Delaunay graph of segments and points. The two template parameters must be models of the `SegmentDelaunayGraphTraits_2` and @@ -44,23 +44,28 @@ the class - `SegmentDelaunayGraphSite_2` - `SegmentDelaunayGraphStorageSite_2` +- `SegmentDelaunayGraphStorageTraits_2` - `SegmentDelaunayGraphDataStructure_2` - `SegmentDelaunayGraphVertexBase_2` +- `SegmentDelaunayGraphFaceBase_2` - `SegmentDelaunayGraphTraits_2` - `SegmentDelaunayGraphHierarchyVertexBase_2` \cgalCRPSection{Classes} -- `CGAL::Segment_Delaunay_graph_2` +- `CGAL::Segment_Delaunay_graph_2` - `CGAL::Segment_Delaunay_graph_site_2` - `CGAL::Segment_Delaunay_graph_storage_site_2` -- `CGAL::Segment_Delaunay_graph_vertex_base_2` +- `CGAL::Segment_Delaunay_graph_storage_site_with_info_2` +- `CGAL::Segment_Delaunay_graph_storage_traits_2` +- `CGAL::Segment_Delaunay_graph_storage_traits_with_info_2` +- `CGAL::Segment_Delaunay_graph_vertex_base_2` +- `CGAL::Segment_Delaunay_graph_face_base_2` - `CGAL::Segment_Delaunay_graph_traits_2` - `CGAL::Segment_Delaunay_graph_traits_without_intersections_2` - `CGAL::Segment_Delaunay_graph_filtered_traits_2` - `CGAL::Segment_Delaunay_graph_filtered_traits_without_intersections_2` -- `CGAL::Segment_Delaunay_graph_hierarchy_2` +- `CGAL::Segment_Delaunay_graph_hierarchy_2` - `CGAL::Segment_Delaunay_graph_hierarchy_vertex_base_2` */ - diff --git a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Segment_Delaunay_graph_2.txt b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Segment_Delaunay_graph_2.txt index 03cf5c807c3..306fa9e2a91 100644 --- a/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Segment_Delaunay_graph_2.txt +++ b/Segment_Delaunay_graph_2/doc/Segment_Delaunay_graph_2/Segment_Delaunay_graph_2.txt @@ -294,8 +294,8 @@ points of intersection. To avoid this redundancy, input points are stored in a container, and the various types of sites (input points and segments, points of intersection, subsegments with one or two points of intersection as endpoints) only store handles to the points -in the container. This is achieved by the -`Segment_Delaunay_graph_storage_site_2` class which is a +in the container. This is achieved with the +`Segment_Delaunay_graph_storage_site_2` class, which is a model of the corresponding concept: `SegmentDelaunayGraphStorageSite_2`. This concept enforces a site to be represented by up to 6 handles (which are very lightweight @@ -449,9 +449,8 @@ class is used, the possible values are `Field_with_sqrt_tag` and \section secsdg2hierarchy The Segment Delaunay Graph Hierarchy -The -`Segment_Delaunay_graph_hierarchy_2` class is the analogue -of the `Triangulation_hierarchy_2` or the +The `Segment_Delaunay_graph_hierarchy_2` +class is the analogue of the `Triangulation_hierarchy_2` or the `Apollonius_graph_hierarchy_2` classes, applied to the segment Delaunay graph. It consists of a hierarchy of segment Delaunay graphs constructed in a manner analogous to the @@ -480,9 +479,9 @@ Delaunay graphs. If `SSTag` is set to `true`, we have segment Delaunay graphs at all levels of the hierarchy. The class -`Segment_Delaunay_graph_hierarchy_2` +`Segment_Delaunay_graph_hierarchy_2` has exactly the same interface and functionality as the -`Segment_Delaunay_graph_2` +`Segment_Delaunay_graph_2` class. Using the segment Delaunay graph hierarchy involves an additional cost in space and time for maintaining the hierarchy. Our experiments have shown that it usually pays off to use the hierarchy diff --git a/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_vertex_base_2.h b/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_vertex_base_2.h index b7876255e4b..d9267828e29 100644 --- a/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_vertex_base_2.h +++ b/Segment_Delaunay_graph_2/include/CGAL/Segment_Delaunay_graph_vertex_base_2.h @@ -11,8 +11,6 @@ // Author(s) : Menelaos Karavelas - - #ifndef CGAL_SEGMENT_DELAUNAY_GRAPH_VERTEX_BASE_2_H #define CGAL_SEGMENT_DELAUNAY_GRAPH_VERTEX_BASE_2_H @@ -21,12 +19,7 @@ #include #include - #include -#include -#include - - namespace CGAL { diff --git a/Segment_Delaunay_graph_Linf_2/include/CGAL/Segment_Delaunay_graph_Linf_2/Voronoi_vertex_sqrt_field_new_C2.h b/Segment_Delaunay_graph_Linf_2/include/CGAL/Segment_Delaunay_graph_Linf_2/Voronoi_vertex_sqrt_field_new_C2.h index b9f1f840a89..8ea07173025 100644 --- a/Segment_Delaunay_graph_Linf_2/include/CGAL/Segment_Delaunay_graph_Linf_2/Voronoi_vertex_sqrt_field_new_C2.h +++ b/Segment_Delaunay_graph_Linf_2/include/CGAL/Segment_Delaunay_graph_Linf_2/Voronoi_vertex_sqrt_field_new_C2.h @@ -579,7 +579,7 @@ private: vort = Aort - (dort)/(FT(2)); } else { vpar = Apar; - vort = Aort - CGAL::sign(dort)*absdpar; + vort = Aort - int(CGAL::sign(dort))*absdpar; } vv = Point_2(vx_, vy_); } @@ -684,11 +684,11 @@ private: vv = Point_2(is_r_horizontal ? (pp.x() + qq.x()) : (comp == LARGER) ? - RT(2)*coordr + CGAL::sign(signrdist)*pqdist : + RT(2)*coordr + int(CGAL::sign(signrdist))*pqdist : coordr + pp.x(), is_r_horizontal ? (comp == LARGER) ? - RT(2)*coordr + CGAL::sign(signrdist)*pqdist : + RT(2)*coordr + int(CGAL::sign(signrdist))*pqdist : coordr + pp.y() : (pp.y() + qq.y()), RT(2)); @@ -725,9 +725,9 @@ private: } else { vv = Point_2(is_r_horizontal ? (pp.x() + qq.x()) : - (RT(2)*coordr + CGAL::sign(sdistf)*pqdist), + (RT(2)*coordr + int(CGAL::sign(sdistf))*pqdist), is_r_horizontal ? - (RT(2)*coordr + CGAL::sign(sdistf)*pqdist) : + (RT(2)*coordr + int(CGAL::sign(sdistf))*pqdist) : (pp.y() + qq.y()), RT(2)); } @@ -771,8 +771,8 @@ private: Point_2(pcoord, lineval) : Point_2(lineval, pcoord); const FT sidelen = (CGAL::max)(CGAL::abs(corner.x() - q.point().x()), CGAL::abs(corner.y() - q.point().y())); - vv = Point_2(FT(2)*corner.x() + signla*sidelen, - FT(2)*corner.y() + signlb*sidelen, + vv = Point_2(FT(2)*corner.x() + int(signla)*sidelen, + FT(2)*corner.y() + int(signlb)*sidelen, FT(2)); return; } @@ -783,8 +783,8 @@ private: Point_2(lineval, qcoord) : Point_2(qcoord, lineval); const FT sidelen = (CGAL::max)(CGAL::abs(corner.x() - p.point().x()), CGAL::abs(corner.y() - p.point().y())); - vv = Point_2(FT(2)*corner.x() + signla*sidelen, - FT(2)*corner.y() + signlb*sidelen, + vv = Point_2(FT(2)*corner.x() + int(signla)*sidelen, + FT(2)*corner.y() + int(signlb)*sidelen, FT(2)); return; } @@ -812,8 +812,8 @@ private: // is shorter than Linf p, q distance const Point_2 corner = pos_slope? Point_2(pcoord, plineval) : Point_2(plineval, pcoord); - vv = Point_2(FT(2)*corner.x() + signla*pqdist, - FT(2)*corner.y() + signlb*pqdist, + vv = Point_2(FT(2)*corner.x() + int(signla)*pqdist, + FT(2)*corner.y() + int(signlb)*pqdist, FT(2)); return; } @@ -829,8 +829,8 @@ private: // is shorter than Linf p, q distance const Point_2 corner = pos_slope? Point_2(qlineval, qcoord) : Point_2(qcoord, qlineval); - vv = Point_2(FT(2)*corner.x() + signla*pqdist, - FT(2)*corner.y() + signlb*pqdist, + vv = Point_2(FT(2)*corner.x() + int(signla)*pqdist, + FT(2)*corner.y() + int(signlb)*pqdist, FT(2)); return; } @@ -1421,12 +1421,12 @@ private: RT ux_, uy_, uz_; if (cmp == LARGER) { ux_ = is_q_hor ? r_coord + p_coord_r : q_coord + p_coord_q; - uy_ = is_q_hor ? (RT(2)*q_coord + CGAL::sign(sdistq)*dx) : - (RT(2)*r_coord + CGAL::sign(sdistr)*dx) ; + uy_ = is_q_hor ? (RT(2)*q_coord + int(CGAL::sign(sdistq))*dx) : + (RT(2)*r_coord + int(CGAL::sign(sdistr))*dx) ; } else if (cmp == SMALLER) { uy_ = is_r_hor ? r_coord + p_coord_r : q_coord + p_coord_q; - ux_ = is_r_hor ? (RT(2)*q_coord + CGAL::sign(sdistq)*dy) : - (RT(2)*r_coord + CGAL::sign(sdistr)*dy) ; + ux_ = is_r_hor ? (RT(2)*q_coord + int(CGAL::sign(sdistq))*dy) : + (RT(2)*r_coord + int(CGAL::sign(sdistr))*dy) ; } else { ux_ = is_q_hor ? r_coord + p_coord_r : q_coord + p_coord_q; uy_ = is_q_hor ? q_coord + p_coord_q : r_coord + p_coord_r; diff --git a/Set_movable_separability_2/include/CGAL/Set_movable_separability_2/Single_mold_translational_casting/pullout_directions.h b/Set_movable_separability_2/include/CGAL/Set_movable_separability_2/Single_mold_translational_casting/pullout_directions.h index 25045340e0f..8c0a4a80baa 100644 --- a/Set_movable_separability_2/include/CGAL/Set_movable_separability_2/Single_mold_translational_casting/pullout_directions.h +++ b/Set_movable_separability_2/include/CGAL/Set_movable_separability_2/Single_mold_translational_casting/pullout_directions.h @@ -129,7 +129,7 @@ pullout_directions //is true if segment_outer_circle \in [first,clock_first,clock_second] if (f_between_ab && s_between_ab) { // std::cout<<"case 1"<)(std::pow((FT) 1.f - (FT) largest_candidate - / (FT(num_pts) * (octree_depth+1) * (1 << (m_required_samples - 1))), (int) num_candidates), (FT) 1); + return (std::min)(std::pow(FT(1) - FT(largest_candidate) + / (FT(num_pts) * FT(octree_depth+1) + * FT(1 << (m_required_samples - 1))), + int(num_candidates)), FT(1)); } private: diff --git a/Shape_detection/test/Shape_detection/test_validity_sampled_data.cpp b/Shape_detection/test/Shape_detection/test_validity_sampled_data.cpp index 95159a9d2ba..b7c5c2ab9a1 100644 --- a/Shape_detection/test/Shape_detection/test_validity_sampled_data.cpp +++ b/Shape_detection/test/Shape_detection/test_validity_sampled_data.cpp @@ -20,6 +20,9 @@ #include +// Uncomment this line to run expensive test +// #define CGAL_SHAPE_DETECTION_RUN_EXPENSIVE_TESTS + namespace SD = CGAL::Shape_detection; using Kernel = CGAL::Simple_cartesian; @@ -64,7 +67,7 @@ int main (int argc, char** argv) test_copied_point_cloud (points, 2); test_copied_point_cloud (points, 5); test_copied_point_cloud (points, 10); -#ifndef CGAL_TEST_SUITE // Disable tests too large for testsuite +#ifdef CGAL_SHAPE_DETECTION_RUN_EXPENSIVE_TESTS test_copied_point_cloud (points, 20); test_copied_point_cloud (points, 50); #endif diff --git a/Solver_interface/doc/Solver_interface/Solver_interface.txt b/Solver_interface/doc/Solver_interface/Solver_interface.txt index 587442df349..e5fded45ffa 100644 --- a/Solver_interface/doc/Solver_interface/Solver_interface.txt +++ b/Solver_interface/doc/Solver_interface/Solver_interface.txt @@ -118,7 +118,7 @@ This package is the result of the increasing needs for linear solvers in \cgal. The first packages that introduced the solver concepts were \ref PkgSurfaceMeshParameterization, \ref PkgPoissonSurfaceReconstruction3 and \ref PkgJetFitting3. At that time, these packages were relying -on \sc{Taucs}, \sc{LAPACK}, \sc{BLAS} and \sc{OpenNL}. Gaël Guennebaud +on \taucs, \lapack, \blas and \opennl. Gaël Guennebaud then introduced new models using the \ref thirdpartyEigen library that became the only supported models by \cgal. Later on the packages \ref PkgSurfaceMeshSkeletonization and \ref PkgSurfaceMeshDeformation diff --git a/Spatial_searching/include/CGAL/Kd_tree.h b/Spatial_searching/include/CGAL/Kd_tree.h index f4cf65bd057..4e8eb8abaa3 100644 --- a/Spatial_searching/include/CGAL/Kd_tree.h +++ b/Spatial_searching/include/CGAL/Kd_tree.h @@ -281,10 +281,8 @@ public: template Kd_tree(InputIterator first, InputIterator beyond, Splitter s = Splitter(),const SearchTraits traits=SearchTraits()) - : traits_(traits),split(s), built_(false), removed_(false) - { - pts.insert(pts.end(), first, beyond); - } + : traits_(traits), split(s), pts(first, beyond), built_(false), removed_(false) + { } bool empty() const { return pts.empty(); diff --git a/Spatial_sorting/doc/Spatial_sorting/CGAL/Multiscale_sort.h b/Spatial_sorting/doc/Spatial_sorting/CGAL/Multiscale_sort.h index e6f85f14238..acb46863901 100644 --- a/Spatial_sorting/doc/Spatial_sorting/CGAL/Multiscale_sort.h +++ b/Spatial_sorting/doc/Spatial_sorting/CGAL/Multiscale_sort.h @@ -8,7 +8,7 @@ Given a range of `n` points:
    1. it applies `Sort` on the last `(1 - ratio) * n` points,
    2. it recurses on the first `ratio * n` points, -stopping when there are less than `threshold` points. +stopping when there are fewer than `threshold` points.
    */ diff --git a/Spatial_sorting/include/CGAL/Hilbert_sort_median_d.h b/Spatial_sorting/include/CGAL/Hilbert_sort_median_d.h index df4c3858e5c..a88b3926006 100644 --- a/Spatial_sorting/include/CGAL/Hilbert_sort_median_d.h +++ b/Spatial_sorting/include/CGAL/Hilbert_sort_median_d.h @@ -114,7 +114,7 @@ public: current_dir = (current_dir +1) % _dimension; }while (current_dir != last_dir); - if ( end-begin < two_to_dim) return; // less than 2^dim points + if ( end-begin < two_to_dim) return; // fewer than 2^dim points /////////////start recursive calls last_dir = (direction + _dimension -1) % _dimension; diff --git a/Straight_skeleton_2/doc/Straight_skeleton_2/Straight_skeleton_2.txt b/Straight_skeleton_2/doc/Straight_skeleton_2/Straight_skeleton_2.txt index 9180253eda1..f795e14f2a3 100644 --- a/Straight_skeleton_2/doc/Straight_skeleton_2/Straight_skeleton_2.txt +++ b/Straight_skeleton_2/doc/Straight_skeleton_2/Straight_skeleton_2.txt @@ -266,7 +266,7 @@ If `Polygon_with_holes_2` is used, you can pass an instance of it directly to th \subsection Straight_skeleton_2CreateOffsetPolygonsfrom Create Offset Polygons from a Straight Skeleton -If you already have a straight skeleton instance, the simpler way to generate offset polygons is to call `create_offset_polygons_2()` as shown in the next example, passing the desired offset and the straight skeleton. You can reuse the same skeleton to generate offsets at a different distance, which is recommended because producing the straight skeleton is much slower then generating offset polygons. +If you already have a straight skeleton instance, the simpler way to generate offset polygons is to call `create_offset_polygons_2()` as shown in the next example, passing the desired offset and the straight skeleton. You can reuse the same skeleton to generate offsets at a different distance, which is recommended because producing the straight skeleton is much slower than generating offset polygons. \cgalExample{Straight_skeleton_2/Create_offset_polygons_2.cpp} diff --git a/Straight_skeleton_2/include/CGAL/Straight_skeleton_builder_2.h b/Straight_skeleton_2/include/CGAL/Straight_skeleton_builder_2.h index 3873a6c54c4..c38e416ab4b 100644 --- a/Straight_skeleton_2/include/CGAL/Straight_skeleton_builder_2.h +++ b/Straight_skeleton_2/include/CGAL/Straight_skeleton_builder_2.h @@ -1360,7 +1360,7 @@ public: } else { - CGAL_STSKEL_BUILDER_TRACE(0,"Degenerate contour (less than 3 non-degenerate vertices)."); + CGAL_STSKEL_BUILDER_TRACE(0,"Degenerate contour (fewer than 3 non-degenerate vertices)."); } } else diff --git a/Stream_support/include/CGAL/IO/3MF/write_3mf.h b/Stream_support/include/CGAL/IO/3MF/write_3mf.h index 2b79ec366d0..b8e55897def 100644 --- a/Stream_support/include/CGAL/IO/3MF/write_3mf.h +++ b/Stream_support/include/CGAL/IO/3MF/write_3mf.h @@ -260,7 +260,7 @@ bool write_points(const PointRange& points, return false; } - //add 3 demmy vertices to be sure to have a valid triangle and accept point sets with less than 3 vertices. + //add 3 dummy vertices to be sure to have a valid triangle and accept point sets with fewer than 3 vertices. for(int i = 0; i< 3; ++i) pVertices.push_back(tmf_internal::fnCreateVertex(0,0,0)); diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/CGAL/Curves_on_surface_topology.h b/Surface_mesh_topology/doc/Surface_mesh_topology/CGAL/Curves_on_surface_topology.h index b37e714ee5e..e5d6efc1b0d 100644 --- a/Surface_mesh_topology/doc/Surface_mesh_topology/CGAL/Curves_on_surface_topology.h +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/CGAL/Curves_on_surface_topology.h @@ -39,6 +39,11 @@ namespace Surface_mesh_topology { */ bool is_contractible(const Path_on_surface& p) const; + /*! returns `true` if the closed path `p` is homotopic to some simple cycle. + * @pre `p` must be a closed path on `amesh`. + */ + bool is_homotopic_to_simple_cycle(const Path_on_surface& p) const; + /*! returns a non-contractible cycle of type `Path_on_surface` with minimal number of edges. This number of edges is the edge width of the mesh. */ Path_on_surface compute_edge_width() const; @@ -56,6 +61,11 @@ namespace Surface_mesh_topology { /*! returns a vector of darts representing a non-contractible curve with a minimal number of intersection with the graph of the mesh. This curve can be described by the alternating sequence of faces and vertices it goes through, so that each dart in the returned vector belongs to both a face and the next vertex in the alternating sequence. (Here, faces and vertices are viewed as subsets of darts.) The size of the returned vector is the face width of the mesh. */ std::vector compute_face_width() const; + + /*! set whether the function should output error message to `std::cerr` when the prerequisite of the argument(s) is not met. + * Affects \link Surface_mesh_topology::Curves_on_surface_topology::are_freely_homotopic `are_freely_homotopic(p1, p2)`\endlink, \link Surface_mesh_topology::Curves_on_surface_topology::are_homotopic_with_fixed_endpoints `are_homotopic_with_fixed_endpoints(p1, p2)`\endlink, \link Surface_mesh_topology::Curves_on_surface_topology::is_contractible `is_contractible(p)`\endlink, and \link Surface_mesh_topology::Curves_on_surface_topology::is_homotopic_to_simple_cycle `is_homotopic_to_simple_cycle(p)`\endlink + */ + void set_verbose(bool is_verbose); }; /*! diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt b/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt index b85cc68b45c..8337baa4022 100644 --- a/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/Surface_mesh_topology.txt @@ -46,7 +46,14 @@ The second query asks if the curves are freely homotopic while the thir The algorithms used are based on a paper by Erickson and Whittlesey \cgalCite{ew-tcsr-13}, providing a linear time algorithm for the above homotopy tests. This is a simplified version of the linear time algorithm by Lazarus and Rivaud \cgalCite{lr-hts-12}. +\subsection SMTopology_simplicity Simplicity Test +Given a cycle drawn on a surface one can ask if the cycle can be continously deformed to a cycle that does not intersect with itself. Any contractible cycle deforms to a simple cycle but this is not true for more complicated cycles. The algorithm in this section is purely topological and do not assume any geometry on the input surface. + +The algorithm implemented in this package builds a data structure to efficiently answer queries of the following forms: +- Given a combinatorial surface \f$\cal{M}\f$ and a closed combinatorial curve specified as a sequence of edges of \f$\cal{M}\f$, decide if the curve is homotopic to a simple one on \f$\cal{M}\f$. + +The algorithm used is based on a paper by Despré and Lazarus \cgalCite{cgal:dl-cginc-19}, providing a \f$O(n + l\log{l})\f$-time algorithm where \f$n\f$ is the complexity of \f$\cal{M}\f$ and \f$l\f$ is the length of the path. \section SMTopology_HowToUse API Description @@ -120,6 +127,18 @@ the input surface. This is otherwise independent of the size of input surface, Each time a `Surface_mesh_topology::Path_on_surface` is provided for a homotopy test, it is first transformed to an equivalent path in the quadrangulation stored by the `Surface_mesh_topology::Curves_on_surface_topology`. This transformation is transparent to the user who has never access to the quadrangulation. +\subsection SMTopology_Query_Simplicity Testing Simplicity + +Given a `Surface_mesh_topology::Path_on_surface` \f$p\f$, the class `Surface_mesh_topology::Curves_on_surface_topology` provides the following function: + +- \link Surface_mesh_topology::Curves_on_surface_topology::is_homotopic_to_simple_cycle `is_homotopic_to_simple_cycle(p)` \endlink returns `true` if the closed curve \f$p\f$ is homotopic to some simple cycle. + +Like homotopy tests, the first step is to simplify the input combinatorial surface. The algorithm will share the surface with homotopy tests and invoke the simplification if the preprocessing has not been done yet. +\note The user must not modify the input surface as long as simplicity tests are performed with this `Surface_mesh_topology::Curves_on_surface_topology`. + +Each time a `Surface_mesh_topology::Path_on_surface` is provided for a simplicity test, it is first transformed to an equivalent path in the quadrangulation stored by the `Surface_mesh_topology::Curves_on_surface_topology`. This transformation is transparent to the user who has never access to the quadrangulation. + + \section SMTopology_Examples Examples \subsection SMTopology_Example_I_II_III Compute Shortest Non-contractible Cycle @@ -146,6 +165,10 @@ The following example computes the face width, and visualizes it if CGAL_Qt5 is The following example shows how to load an off file and how to create three closed paths on this surface. Contractibility and free homotopy tests are then performed. The example also shows how to use the \cgal viewer if CGAL_Qt5 is enabled. \cgalExample{Surface_mesh_topology/path_homotopy_double_torus.cpp} +\subsection SMTopology_Example_VI Basic Simplicity Test +The following example shows how to test the simplicity of a closed path on a double torus. The original path is visualized if CGAL_Qt5 is enabled. +\cgalExample{Surface_mesh_topology/path_simplicity_double_torus_2.cpp} + \subsection SMTopology_Example_VI_VII Polygonal Schema Here, we show with two examples how to create a surface from a list of faces specified by edge label sequences. In this first example, we build a genus two torus surface from a single face, also called a polygonal schema. See left \cgalFigureRef{fig_sm_incremental-builder} for an illustration. Two closed paths are then created. The paths are freely homotopic but not homotopic with fixed endpoint. @@ -262,9 +285,51 @@ The canonical form of a curve is obtained by flattening its brackets, removing i \subsection SMTopology_Homotopy_Test Homotopy Test It can be proven that the canonical form is uniquely defined and only depends on the homotopy class of the curve. Hence, the curves \f$C'\f$ and \f$D'\f$ in \f$\cal{Q}\f$ are homotopic if and only if their canonical forms are equal. Since each curve is defined as a sequence of (oriented) edges up to a cyclic permutation, we resort to the Knuth-Morris-Pratt algorithm to decide in linear time if the canonical forms are the same up to a cyclic permutation. +\subsection SMTopology_Simplicity_Test Simplicity Test +The simplicity test relies on the fact that a closed curve is homotopic to a simple one if and only if its canonical form can be made intersection free via infinitesimal perturbations together with some homotopy preserving operations. One can imagine each edge in the quadrangulation has a width and each vertex in the quadrangulation has an area so that paths visiting the same vertex/edge multiple times can avoid intersection after perturbation within a vertex or an edge. See \cgalFigureRef{fig_perturbation_sample} for an example. +\cgalFigureBegin{fig_perturbation_sample,perturbation_sample.svg} + Applying a perturbation to remove 2 intersections between the red and the blue subpaths. + \cgalFigureEnd + +Such a perturbation can be encoded as a transverse ordering of the edges from the canonical form which traverse the same edge in the quadrangulation. The idea of the algorithm is to traverse the canonical form, one edge at a time, to inductively build such orderings and try to avoid intersection as best as we can. + +\subsubsection SMTopology_Simplicity_Test_Primitive Detect Repetition +There is an easy case where we know for sure that a closed curve cannot be deformed to simple one: If the canonical form can be expressed as concatenation of two or more copies of the same path. So the first step of the algorithm is to detect repetition. + +Let \f$P\f$ be a path and let \f$+\f$ be the operator of concatenation. It can be shown that \f$P\f$ contains no repetition if and only if there are only 2 matchings of \f$P\f$ in \f$P+P\f$ (matching the first and the second copy). The algorithm resorts to the Knuth-Morris-Pratt algorithm to decide in linear time if the canonical form contains repetitions. + +\subsubsection SMTopology_Simplicity_Test_Switch Avoid Crossing by Switching +Apart from applying perturbation, the algorithm also tries to avoid crossings using a homotopy-preserving operation called as a switch. A switch is triggered whenever an intersection could be avoided by turning a left L-shaped subpath into a right L-shaped subpath. See \cgalFigureRef{fig_switch_sample} for an example. +\cgalFigureBegin{fig_switch_sample,switch_sample.svg} + Top-left, an intersection between the red subpath and the green subpath at the start of the left L-shaped red subpath. Top-right, switch the left L-shape to right L-shape to avoid the intersection. Bottom-left or right, no switch is performed because no intersection can be avoided. + \cgalFigureEnd + +\subsubsection SMTopology_Simplicity_Test_Relative_Order Decide Relative Order +As the algorithm inductively builds orderings, it has to determine a relative order between the edge being processed and the edges that have been ordered. There are three cases to consider. + +-# The current edge and its predecessor, say \f$e\f$, form a subpath of length two so that a parallel copy of this subpath has already been processed, and \f$e\f$ is adjacent to its parallel copy in the previously constructed ordering. In this case, the current edge must be adjacent to its copy in the transverse ordering. See \cgalFigureRef{fig_relative_order_corner}. +\cgalFigureBegin{fig_relative_order_corner,relative_order_corner.svg} + The red edge is being processed. The blue edge is adjacent to the green edge (the predecessor \f$e\f$ of the red edge) in the previously constructed ordering and forms the same turn (blue-pink turn) as the green-red turn. The red edge should be right next to the pink edge in the ordering so as to avoid crossings. + \cgalFigureEnd + +-# When the previous situation does not occur, the current edge has to be compared against every parallel copy already processed. In this case, the predecessors of the copy and of the current edge form a Y shape with the current edge. The circular order of the edges in this Y can be used to determine the relative order between the current edge and its copy. See \cgalFigureRef{fig_relative_order_normal}. +\cgalFigureBegin{fig_relative_order_normal,relative_order_normal.svg} + The red edge is being processed and is compared against the pink edge. Since the green edge (the predecessor of the red edge) is to the right of the blue edge around the vertex, the red edge must be to the right of the pink edge in the transverse ordering. + \cgalFigureEnd + +-# There is one special case where the comparison of the current edge with a parallel copy cannot be deduced form previous computations: When this copy happens to be the very first edge processed in the traversal. Indeed, the predecessor of the first edge (aka the last edge of the path) has not been processed yet. If the last edge runs parallel to the predecessor of the current edge, we cannot determine their relative order. So the idea is to keep following the predecessors of the current edge and of the first edge until they diverge, at which point the relative order around the vertex can be used to determine the relative order. See \cgalFigureRef{fig_relative_order_first}. This can be precomputed by finding all the longest common suffixes of the path against its circular shifts. A modified Knuth-Morris-Pratt algorithm is applied to preprocess the path in linear time. +\cgalFigureBegin{fig_relative_order_first,relative_order_first.svg} + The red edge is being processed and is compared against the pink edge which is the first edge of the path. The blue and green edges are the first diverging pair when tracing backward. The dashed line means that edges have not been processed yet. Since the green edge lies to the right of the blue edge around the vertex, the red edge must be to the right of the pink edge in the ordering. + \cgalFigureEnd + +The transverse orderings are stored in red-black trees, one for each edge of the quadrangulation. So each insertion or search takes \f$O(\log{l})\f$ time, where \f$l\f$ is the length of the closed curve. + +\subsubsection SMTopology_Simplicity_Test_Verification Verify Ordering +After computing a tentative ordering within the edges of the path, we have to verify that such an ordering could result in an intersection free arrangement. Since there is no intersection within an edge, we only need to verify this for each vertex in the quadrangulation. Each vertex is naturally associated with a circular ordering of the incident path edges by concatenating clockwise the orderings computed for every incident edge in the quadrangulation. We consider the two consecutive edges composing a turn (one going in the vertex, one going out of the vertex) at the vertex being verified as a pair. The ordering at the vertex is intersection free if and only if there is no two pairs crossing each other according to the clockwise ordering around the vertex. In other words, for any two pairs \f$(a, a')\f$ and \f$(b, b')\f$, none of the subsequences \f$a, b, a', b'\f$ or \f$a, b', a', b\f$ should appear in the clockwise ordering. This is very similar to verifying balanced parentheses in a string. We traverse clockwise at each vertex and use a stack-based algorithm to verify in linear time that the ordering produces a cycle without self-intersection. + \section Implementation History -The code was developed in 2018 by Guillaume Damiand and Francis Lazarus. Felix Castillon contributed to the extension of the homotopy test to the case of surfaces with boundaries. Thien Hoang added methods to compute shortest non-contractible cycles, edge width and face width as part of the program Google Summer of Code 2019. +The code was developed in 2018 by Guillaume Damiand and Francis Lazarus. Felix Castillon contributed to the extension of the homotopy test to the case of surfaces with boundaries. Thien Hoang added methods to compute shortest non-contractible cycles, edge width and face width as part of the program Google Summer of Code 2019. Shuhao Tan added methods to test simplicity of a closed curve as part of the program Google Summer of Code 2020. */ } /* namespace CGAL */ diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/examples.txt b/Surface_mesh_topology/doc/Surface_mesh_topology/examples.txt index 0d740fdbd48..1c5bdf3ff9e 100644 --- a/Surface_mesh_topology/doc/Surface_mesh_topology/examples.txt +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/examples.txt @@ -5,5 +5,7 @@ \example Surface_mesh_topology/path_homotopy_double_torus.cpp \example Surface_mesh_topology/path_homotopy_with_symbols.cpp \example Surface_mesh_topology/path_homotopy_with_symbols_2.cpp +\example Surface_mesh_topology/path_simplicity_double_torus.cpp +\example Surface_mesh_topology/path_simplicity_double_torus_2.cpp \example Surface_mesh_topology/open_path_homotopy.cpp */ diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/fig/perturbation_sample.svg b/Surface_mesh_topology/doc/Surface_mesh_topology/fig/perturbation_sample.svg new file mode 100644 index 00000000000..fa5b1dd3500 --- /dev/null +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/fig/perturbation_sample.svg @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + u + v + e + e + v + u + + + + + + + + + + diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/fig/relative_order_corner.svg b/Surface_mesh_topology/doc/Surface_mesh_topology/fig/relative_order_corner.svg new file mode 100644 index 00000000000..a5751b57668 --- /dev/null +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/fig/relative_order_corner.svg @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/fig/relative_order_first.svg b/Surface_mesh_topology/doc/Surface_mesh_topology/fig/relative_order_first.svg new file mode 100644 index 00000000000..c1b1aa15d57 --- /dev/null +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/fig/relative_order_first.svg @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/fig/relative_order_normal.svg b/Surface_mesh_topology/doc/Surface_mesh_topology/fig/relative_order_normal.svg new file mode 100644 index 00000000000..96d3c467480 --- /dev/null +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/fig/relative_order_normal.svg @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/Surface_mesh_topology/doc/Surface_mesh_topology/fig/switch_sample.svg b/Surface_mesh_topology/doc/Surface_mesh_topology/fig/switch_sample.svg new file mode 100644 index 00000000000..0cccf3f118f --- /dev/null +++ b/Surface_mesh_topology/doc/Surface_mesh_topology/fig/switch_sample.svg @@ -0,0 +1,819 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Surface_mesh_topology/examples/Surface_mesh_topology/CMakeLists.txt b/Surface_mesh_topology/examples/Surface_mesh_topology/CMakeLists.txt index 68cd4f5a819..2572662c735 100644 --- a/Surface_mesh_topology/examples/Surface_mesh_topology/CMakeLists.txt +++ b/Surface_mesh_topology/examples/Surface_mesh_topology/CMakeLists.txt @@ -21,20 +21,23 @@ endif() # add_definitions("-D_GLIBCXX_DEBUG") set(SOURCE_FILES - edgewidth_lcc.cpp - edgewidth_surface_mesh.cpp - facewidth.cpp - map_2_constructor.cpp - open_path_homotopy.cpp - path_homotopy.cpp - path_homotopy_double_torus.cpp - path_homotopy_torus.cpp - path_homotopy_with_sm_and_polyhedron.cpp - path_homotopy_with_symbols_2.cpp - path_homotopy_with_symbols.cpp - shortest_noncontractible_cycle_2.cpp - shortest_noncontractible_cycle.cpp - unsew_edgewidth_repeatedly.cpp) + edgewidth_lcc.cpp + edgewidth_surface_mesh.cpp + facewidth.cpp + map_2_constructor.cpp + open_path_homotopy.cpp + path_homotopy.cpp + path_homotopy_double_torus.cpp + path_homotopy_torus.cpp + path_homotopy_with_sm_and_polyhedron.cpp + path_homotopy_with_symbols_2.cpp + path_homotopy_with_symbols.cpp + path_simplicity_double_torus.cpp + path_simplicity_double_torus_2.cpp + shortest_noncontractible_cycle_2.cpp + shortest_noncontractible_cycle.cpp + unsew_edgewidth_repeatedly.cpp + ) foreach(cppfile ${SOURCE_FILES}) create_single_source_cgal_program("${cppfile}") @@ -48,8 +51,9 @@ if(CGAL_Qt5_FOUND) target_link_libraries(path_homotopy PUBLIC CGAL::CGAL_Qt5) target_link_libraries(path_homotopy_double_torus PUBLIC CGAL::CGAL_Qt5) target_link_libraries(path_homotopy_torus PUBLIC CGAL::CGAL_Qt5) - target_link_libraries(path_homotopy_with_sm_and_polyhedron - PUBLIC CGAL::CGAL_Qt5) + target_link_libraries(path_homotopy_with_sm_and_polyhedron PUBLIC CGAL::CGAL_Qt5) + target_link_libraries(path_simplicity_double_torus PUBLIC CGAL::CGAL_Qt5) + target_link_libraries(path_simplicity_double_torus_2 PUBLIC CGAL::CGAL_Qt5) target_link_libraries(shortest_noncontractible_cycle_2 PUBLIC CGAL::CGAL_Qt5) target_link_libraries(shortest_noncontractible_cycle PUBLIC CGAL::CGAL_Qt5) target_link_libraries(unsew_edgewidth_repeatedly PUBLIC CGAL::CGAL_Qt5) diff --git a/Surface_mesh_topology/examples/Surface_mesh_topology/path_simplicity_double_torus.cpp b/Surface_mesh_topology/examples/Surface_mesh_topology/path_simplicity_double_torus.cpp new file mode 100644 index 00000000000..762c9f986d9 --- /dev/null +++ b/Surface_mesh_topology/examples/Surface_mesh_topology/path_simplicity_double_torus.cpp @@ -0,0 +1,115 @@ +#include +#include +#include +#include +#include + +typedef CGAL::Linear_cell_complex_for_combinatorial_map<2,3> LCC_3_cmap; +using namespace CGAL::Surface_mesh_topology; + +/////////////////////////////////////////////////////////////////////////////// +void create_path_1(Path_on_surface& p) +{ + p.push_back_by_index(438); // Its starting dart + for (int i=0; i<5; ++i) + { p.extend_positive_turn(2); } // Extend the path + p.extend_positive_turn(1); + for (int i=0; i<7; ++i) + { p.extend_positive_turn(2); } +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_2(Path_on_surface& p) +{ + p.push_back_by_index({14, 15, 391, 392, 395, 227, 223, 313, 318, 326, 82, + 87, 431, 160, 435, 753, 754, 756, 757, 674, 678, 850, + 483, 480, 475, 470, 893, 618, 622, 548, 551, 795, + 797, 806, 637, 634, 638, 872, 521, 376, 180, 424, + 88, 95, 440, 152, 149, 21}); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_3(Path_on_surface& p) +{ + p.push_back_by_index(473); // Its starting dart + p.extend_positive_turn(1); // Extend the path + p.extend_positive_turn(3); + for (int i=0; i<7; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + p.extend_positive_turn(1); + for (int i=0; i<3; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + p.extend_positive_turn(1); + for (int i=0; i<2; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); + for (int i=0; i<3; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + p.extend_positive_turn(2); + p.extend_positive_turn(1); + for (int i=0; i<2; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + for (int i=0; i<3; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); + p.extend_positive_turn(1); + for (int i=0; i<2; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); + for (int i=0; i<2; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + for (int i=0; i<3; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + for (int i=0; i<3; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); + p.extend_positive_turn(3); + for (int i=0; i<2; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + p.extend_positive_turn(2); +} + +/////////////////////////////////////////////////////////////////////////////// +int main(int argc, char** argv) +{ + bool draw=(argc>1?std::string(argv[1])=="-draw":false); + LCC_3_cmap lcc; + if (!CGAL::load_off(lcc, "data/double-torus.off")) + { + std::cout<<"ERROR reading file data/double-torus.off"< cst(lcc); + Path_on_surface p1(lcc), p2(lcc), p3(lcc); + create_path_1(p1); + create_path_2(p2); + create_path_3(p3); + + + bool res1=cst.is_homotopic_to_simple_cycle(p1); + std::cout<<"Path p1 (pink) "<<(res1?"IS":"IS NOT") + <<" simple."< +#include +#include +#include +#include + +typedef CGAL::Linear_cell_complex_for_combinatorial_map<2,3> LCC_3_cmap; +using namespace CGAL::Surface_mesh_topology; + +/////////////////////////////////////////////////////////////////////////////// +void create_path(Path_on_surface& p) +{ + p.push_back_by_index(682); // Its starting dart + for (int i=0; i<11; ++i) + { p.extend_positive_turn(2); } // Extend the path + p.extend_positive_turn(3); + for (int i=0; i<5; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); + p.extend_positive_turn(2); + p.extend_positive_turn(3); + for (int i=0; i<2; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + for (int i=0; i<5; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); + for (int i=0; i<2; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); + for (int i=0; i<2; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + p.extend_positive_turn(2); + p.extend_positive_turn(1); + for (int i=0; i<8; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); + for (int i=0; i<4; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + for (int i=0; i<5; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(3); + for (int i=0; i<5; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); + for (int i=0; i<3; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); + p.extend_positive_turn(1); + for (int i=0; i<11; ++i) + { p.extend_positive_turn(2); } + p.extend_positive_turn(1); +} + +/////////////////////////////////////////////////////////////////////////////// +int main(int argc, char** argv) +{ + bool draw=(argc>1?std::string(argv[1])=="-draw":false); + LCC_3_cmap lcc; + if (!CGAL::load_off(lcc, "data/double-torus.off")) + { + std::cout<<"ERROR reading file data/double-torus.off"< cst(lcc); + Path_on_surface p(lcc); + create_path(p); + + bool res=cst.is_homotopic_to_simple_cycle(p); + std::cout<<"Path p (pink) "<<(res?"IS":"IS NOT") + <<" simple."<is_contractible(p, display_time); + return m_minimal_quadrangulation->is_contractible(p, display_time, m_is_verbose); } /// @return true iff 'p1' and 'p2' are freely homotopic. @@ -85,7 +86,7 @@ public: { compute_minimal_quadrangulation(display_time); return m_minimal_quadrangulation->are_freely_homotopic(p1, p2, - display_time); + display_time, m_is_verbose); } /// @return true iff 'p1' and 'p2' are base point freely homotopic. @@ -95,7 +96,7 @@ public: { compute_minimal_quadrangulation(display_time); return m_minimal_quadrangulation->are_base_point_homotopic(p1, p2, - display_time); + display_time, m_is_verbose); } //================================================================================ @@ -166,11 +167,32 @@ public: return m_facewidth->compute_face_width(display_time); } +//================================================================================ +// Test whether a path is homotopic to a simple cycle + + bool is_homotopic_to_simple_cycle(const Path_on_surface& p, + bool display_time=false) const + { + compute_minimal_quadrangulation(display_time); + return m_minimal_quadrangulation->is_homotopic_to_simple_cycle(p, display_time, m_is_verbose); + } + +//================================================================================ +// Utility functions + + // Set whether to display warning message in `std::cerr` when input doesn't meet + // prerequesite + void set_verbose(bool is_verbose) + { + m_is_verbose = is_verbose; + } + protected: const Mesh& m_original_mesh; mutable std::unique_ptr m_minimal_quadrangulation; mutable std::unique_ptr m_shortest_noncontractible_cycle; mutable std::unique_ptr m_facewidth; + bool m_is_verbose; }; } // namespace Surface_mesh_topology diff --git a/Surface_mesh_topology/include/CGAL/Path_on_surface.h b/Surface_mesh_topology/include/CGAL/Path_on_surface.h index 5eecbcb9b65..7a56a82156a 100644 --- a/Surface_mesh_topology/include/CGAL/Path_on_surface.h +++ b/Surface_mesh_topology/include/CGAL/Path_on_surface.h @@ -1099,6 +1099,39 @@ public: } } + /// @return the primitive root and the power of the path in the sense of string. + /// use the linear Knuth-Morris-Pratt search + std::pair factorize() { + CGAL_assertion(is_valid()); + if (!is_closed()) { + // if a path is not closed, it is already primitive + return std::make_pair(Path_on_surface(*this), 1); + } + + Self pp1(*this); + pp1.simplify_flips(); + Self pp2(pp1); + /// create a path of (*this)->(*this) + pp2 += pp1; + + /// Match (*this) to (*this)->(*this) with the first dart removed + auto itMatch = boost::algorithm::knuth_morris_pratt_search(pp2.m_path.begin() + 1, + pp2.m_path.end(), + pp1.m_path.begin(), + pp1.m_path.end()) +#if BOOST_VERSION>=106200 + .first +#endif + ; + /// It can be proved that the first match location is the length of match + auto primitiveSize = itMatch - pp2.m_path.begin(); + auto originalLength = pp1.length(); + CGAL_assertion(pp1.length() % primitiveSize == 0); + pp1.cut(primitiveSize); + CGAL_assertion(pp1.is_closed()); + return std::make_pair(pp1, originalLength / primitiveSize); + } + /// @return the turn between dart number i and dart number i+1. /// (turn is position of the second edge in the cyclic ordering of /// edges starting from the first edge around the second extremity @@ -1133,6 +1166,23 @@ public: get_opposite_ith_real_dart(i)); } + /// @return the turn between dart number i-1 and dart number i. + std::size_t prev_positive_turn(std::size_t i) const + { + // CGAL_assertion(is_valid()); + CGAL_assertion(i0); + return next_positive_turn(prev_index(i)); + } + /// @return the negative turn between dart number i-1 and dart number i. + std::size_t prev_negative_turn(std::size_t i) const + { + // CGAL_assertion(is_valid()); + CGAL_assertion(i0); + return next_negative_turn(prev_index(i)); + } + /// Computes all positive turns of this path. std::vector compute_positive_turns() const { diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h index 4481eebc353..174ff1aec75 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Minimal_quadrangulation.h @@ -32,6 +32,8 @@ #include #include #include +#include +#include namespace CGAL { namespace Surface_mesh_topology { @@ -50,6 +52,52 @@ struct Minimal_quadrangulation_local_map_items }; }; +struct Minimal_quadrangulation_simplicity_testing_rbtree_node +{ + Minimal_quadrangulation_simplicity_testing_rbtree_node(std::size_t i=0) + : m_idx(i) {} + + Minimal_quadrangulation_simplicity_testing_rbtree_node *m_parent, *m_left, *m_right; + int m_color; + std::size_t m_idx; +}; + +struct Minimal_quadrangulation_simplicity_testing_rbtree_node_traits +{ + typedef Minimal_quadrangulation_simplicity_testing_rbtree_node node; + typedef Minimal_quadrangulation_simplicity_testing_rbtree_node* node_ptr; + typedef const Minimal_quadrangulation_simplicity_testing_rbtree_node* const_node_ptr; + typedef int color; + + static node_ptr get_parent(const_node_ptr n) { return n->m_parent; } + static void set_parent(node_ptr n, node_ptr parent) { n->m_parent = parent; } + static node_ptr get_left(const_node_ptr n) { return n->m_left; } + static void set_left(node_ptr n, node_ptr left) { n->m_left = left; } + static node_ptr get_right(const_node_ptr n) { return n->m_right; } + static void set_right(node_ptr n, node_ptr right) { n->m_right = right; } + static color get_color(const_node_ptr n) { return n->m_color; } + static void set_color(node_ptr n, color color) { n->m_color = color; } + static color black() { return color(0); } + static color red() { return color(1); } +}; + +struct Minimal_quadrangulation_simplicity_testing_rbtree_value_traits +{ + typedef Minimal_quadrangulation_simplicity_testing_rbtree_node_traits node_traits; + typedef node_traits::node value_type; + typedef node_traits::node_ptr node_ptr; + typedef node_traits::const_node_ptr const_node_ptr; + typedef value_type* pointer; + typedef value_type const* const_pointer; + + static const boost::intrusive::link_mode_type link_mode = boost::intrusive::link_mode_type::normal_link; + + static node_ptr to_node_ptr(value_type &value) { return &value; } + static const_node_ptr to_node_ptr(const value_type &value) { return &value; } + static pointer to_value_ptr(node_ptr n) { return n; } + static const_pointer to_value_ptr(const_node_ptr n) { return n; } +}; + template class Minimal_quadrangulation { @@ -242,14 +290,17 @@ public: /// @return true iff 'p' is contractible. bool is_contractible(const Path_on_surface& p, - bool display_time=false) const + bool display_time=false, bool is_verbose=false) const { if (p.is_empty()) { return true; } if (!p.is_closed()) { - std::cerr<<"Error: is_contractible requires a closed path."<& p1, const Path_on_surface& p2, - bool display_time=false) const + bool display_time=false, bool is_verbose=false) const { if (p1.is_empty() && p2.is_empty()) { return true; } if ((!p1.is_empty() && !p1.is_closed()) || (!p2.is_empty() && !p2.is_closed())) { - std::cerr<<"Error: are_freely_homotopic requires two closed paths." - <& p1, const Path_on_surface& p2, - bool display_time=false) const + bool display_time=false, bool is_verbose=false) const { if (p1.is_empty() && p2.is_empty()) { return true; } if (p1.is_empty() || p2.is_empty()) { return false; } @@ -365,8 +419,11 @@ public: (p1.back_flip()?p1.back():get_original_map().template beta<1>(p1.back()), p2.back_flip()?p2.back():get_original_map().template beta<1>(p2.back()))) { - std::cerr<<"Error: are_base_point_homotopic requires two paths that" - <<" share the same vertices as extremities."<& p, + bool display_time=false, bool is_verbose=false) const + { + if (p.is_empty()) + { return true; } + + if (!p.is_closed()) + { + if (is_verbose) + { + std::cerr<<"Error: is_homotopic_to_simple_cycle requires a closed path."< + pt=transform_original_path_into_quad_surface_for_torus(p); + + int a, b; + count_edges_of_path_on_torus(pt, a, b); + a = std::abs(a); + b = std::abs(b); + res=((a == 0 && b == 1) || (b == 0 && a == 1) || CGAL::gcd(a, b) - 1 == 0); + } + else if (is_contractible(p)) + { + // genus > 1 and contractible + res=true; + } + else + { + // genus > 1 and not contractible, perform unzip algorithm + internal::Path_on_surface_with_rle + pt=transform_original_path_into_quad_surface_with_rle(p); + pt.canonize(); + // Use non-rle path from now on + Path_on_surface p_canonized(pt); + auto factorization=p_canonized.factorize(); + // If the path length is 1, it must be simple + res = factorization.second <= 1 && factorization.first.length() <= 1; + if (factorization.second <= 1 && !res) + { + // If the curve is not primitive, there must be at least + // one self intersection + + auto& p_original = factorization.first; + p_original.simplify_flips(); + + auto perturbation = compute_perturbation(p_original); + + // Check whether orders form a valid parenthesis expression + res = is_ordering_simple(perturbation.first, perturbation.second); + } + } + + if (display_time) + { + t.stop(); + std::cout<<"[TIME] is_homotopic_to_simple_cycle: "<, std::unordered_map>> compute_perturbation(const Path_on_surface& p) const + { + std::vector pr; + pr.reserve(p.length()); + for(std::size_t i = 0; i < p.length(); ++i) + { + pr.emplace_back(p[i]); + } + + // Compute the backward cyclic KMP failure table for the curve + std::vector suffix_len = compute_common_circular_suffix(p); + std::vector switchable = compute_switchable(p); + + typedef typename boost::intrusive::rbtree> rbtree; + std::vector rb_nodes; + rb_nodes.reserve(pr.size()); + std::unordered_map trees; + + for (std::size_t i = 0; i < pr.size(); ++i) + { + Dart_const_handle dh = pr[i]; + auto dart_id = get_absolute_idx(dh); + rb_nodes.emplace_back(i); + auto& node = rb_nodes.back(); + + // Check whether current darts needs to be switched + if (i > 0 && switchable[i]) + { + // Look at the t-1 turn of [i-1, i, i + 1] + Dart_const_handle dleft = get_local_map().template beta<0, 2>(dh); + size_type dleft_id = get_absolute_idx(dleft); + if(trees[dleft_id].size() > 0) + { + std::size_t max_turn_idx = is_absolutely_directed(dleft) ? trees[dleft_id].begin()->m_idx : trees[dleft_id].rbegin()->m_idx; + Dart_const_handle dprev = get_previous_relative_to(pr, max_turn_idx, dleft); + // If there exists a crossing that can be avoided, switch + if(get_order_relative_to(pr[i - 1], dleft) > get_order_relative_to(dprev, dleft)) + { + switch_dart(pr, i, switchable); + dh = pr[i]; + dart_id = get_absolute_idx(pr[i]); + } + } + } + // Insert current darts + if (trees[dart_id].empty()) + { + trees[dart_id].push_back(node); + } + else + { + // First check whether there is another corner in the previous part of the path + // where it matches p[i - 1] -> p[i] + // If so, p[i] must be inserted adjacent to one such corner + size_type prev_dart_id = get_absolute_idx(pr[i - 1]); + auto it_prev = trees[prev_dart_id].iterator_to(rb_nodes[i - 1]); + if (it_prev != trees[prev_dart_id].begin() && is_same_corner(pr, std::prev(it_prev)->m_idx, i - 1)) + { + auto it_adjacent = trees[dart_id].iterator_to(rb_nodes[get_next_idx_relative_to(pr, std::prev(it_prev)->m_idx, pr[i - 1])]); + if(is_absolutely_directed(pr[i - 1]) == is_absolutely_directed(dh)) + { + trees[dart_id].insert_before(std::next(it_adjacent), node); + } + else + { + trees[dart_id].insert_before(it_adjacent, node); + } + } + else if (std::next(it_prev) != trees[prev_dart_id].end() && is_same_corner(pr, std::next(it_prev)->m_idx, i - 1)) + { + auto it_adjacent = trees[dart_id].iterator_to(rb_nodes[get_next_idx_relative_to(pr, std::next(it_prev)->m_idx, pr[i-1])]); + if(is_absolutely_directed(pr[i - 1]) == is_absolutely_directed(dh)) + { + trees[dart_id].insert_before(it_adjacent, node); + } + else + { + trees[dart_id].insert_before(std::next(it_adjacent), node); + } + } + else + { + /// There is no same corner in the previous of the path + /// Perform usual unzip insertion + auto less_than_in_tree = is_absolutely_directed(dh)? + std::function{std::greater()} : std::function{std::less()}; + auto comparator = [this, &pr, &p, &suffix_len, &less_than_in_tree] (const std::size_t& key, const rbtree::value_type& b) -> bool { + if (b.m_idx == 0 && pr[key] == pr[0]) + { + if(pr[key] != p[key]) { + // current edge was switched so it should always be on the right side (more clockwise) + return less_than_in_tree(0, 1); + } + /// Comparing to pr[0], needs to check longest suffix + std::size_t current_dividing_idx = key + p.length() - 1 - suffix_len[key - 1]; + std::size_t path_end_dividing_idx = p.length() - 1 - suffix_len[key - 1]; + std::size_t last_same_idx = (path_end_dividing_idx == p.length() - 1) ? 0 : path_end_dividing_idx + 1; + if (current_dividing_idx >= p.length()) + { + current_dividing_idx -= p.length(); + } + Dart_const_handle dbase = p[last_same_idx], + dcur = p[current_dividing_idx], + d0 = p[path_end_dividing_idx]; + + std::size_t key_prev_order = this->get_order_relative_to(dcur, dbase); + std::size_t b_prev_order = this->get_order_relative_to(d0, dbase); + return less_than_in_tree(key_prev_order, b_prev_order); + } + else + { + std::size_t key_prev_order = this->get_order_relative_to(pr[key - 1], pr[key]); + Dart_const_handle bprev = this->get_previous_relative_to(pr, b.m_idx, pr[key]); + std::size_t b_prev_order = this->get_order_relative_to(bprev, pr[key]); + return less_than_in_tree(key_prev_order, b_prev_order); + } + }; + auto it_after = trees[dart_id].upper_bound(i, comparator); + trees[dart_id].insert_before(it_after, node); + } + } + } + + Path_on_surface p_perturbed(get_local_map()); + for(const auto& dp: pr) + { + p_perturbed.push_back(dp); + } + std::unordered_map> ordering; + for(const auto& edge_ordering: trees) + { + std::transform(edge_ordering.second.begin(), edge_ordering.second.end(), + std::back_inserter(ordering[edge_ordering.first]), + [] (const rbtree::value_type& node) + { + return node.m_idx; + }); + } + return std::make_pair(p_perturbed, ordering); + } + + /// @return true iff the ordering of the edges in the input path is intersection free + bool is_ordering_simple(const Path_on_surface& p, const std::unordered_map>& ordering) const + { + bool res = true; + auto marktemp=get_local_map().get_new_mark(); + for (auto it=get_local_map().darts().begin(); + res && it!=get_local_map().darts().end(); ++it) + { + if (!get_local_map().is_marked(it, marktemp)) + { + std::stack> parenthesis_pairing; + Dart_const_handle dh2=it; + do + { + get_local_map().mark(dh2, marktemp); + auto dart_id = get_absolute_idx(dh2); + auto handle_node = [&dh2, &p, &parenthesis_pairing] (const std::size_t& idx) { + auto curr_dart = std::make_pair(idx, p[idx] == dh2); + if (parenthesis_pairing.empty()) + { + parenthesis_pairing.push(curr_dart); + } + else + { + /// We can cancel a pair of dart iff + /// 1) They are adjacent in the path (wrap around for the last dart) + /// 2) The first one is going in and the second one is going out + auto prev_dart = parenthesis_pairing.top(); + auto next_dart = curr_dart; + if(!next_dart.second) + { + std::swap(next_dart, prev_dart); + } + if ((next_dart.first - prev_dart.first == 1 || (next_dart.first == 0 && prev_dart.first == p.length() - 1)) && + (!prev_dart.second && next_dart.second)) + { + parenthesis_pairing.pop(); + } + else + { + parenthesis_pairing.push(curr_dart); + } + } + }; + auto it_dart_ordering = ordering.find(dart_id); + if (it_dart_ordering != ordering.cend()) + { + if (is_absolutely_directed(dh2)) + { + std::for_each(it_dart_ordering->second.cbegin(), it_dart_ordering->second.cend(), handle_node); + } + else + { + std::for_each(it_dart_ordering->second.crbegin(), it_dart_ordering->second.crend(), handle_node); + } + } + dh2 = get_local_map().template beta<2, 1>(dh2); + } + while(dh2!=it); + res = res && parenthesis_pairing.empty(); + } + } + get_local_map().free_mark(marktemp); + return res; + } + + /// Compute the longest common suffix of a path against all of it circular shifts + /// Based on a modification of Knuth-Morris-Pratt algorithm + std::vector compute_common_circular_suffix(const Path_on_surface& p) const + { + Path_on_surface q(p); + q += p; + std::vector suffix_len(q.length()); + std::size_t match_begin = 0, + match_end = 0; + suffix_len.back() = q.length(); + for (std::size_t i = 1; i < q.length(); ++i) { + std::size_t match_idx = q.length() - 1 - i; + if (i >= match_end || i + suffix_len[match_idx + match_begin] >= match_end) { + match_begin = i; + if (i >= match_end) { + match_end = i; + } + while (match_end < q.length() && q[q.length() - 1 - match_end] == q[q.length() - 1 - (match_end - i)]) { + ++match_end; + } + suffix_len[match_idx] = match_end - match_begin; + } + else { + suffix_len[match_idx] = suffix_len[match_idx + match_begin]; + } + } + + std::vector result(suffix_len.begin() + p.length(), suffix_len.end()); + for (std::size_t i = 0; i < result.size(); ++i) { + result[i] = (std::min)(result[i], p.length()); + } + return result; + } + + /// Compute a boolean array of whether there is an left-L-shape at i-th dart, aka whether it is swicthable + std::vector compute_switchable(const Path_on_surface& p) const + { + std::vector switchable(p.length(), false); + /// Skip the last dart and the first dart since it can never be switched, nor can it + /// be the second last dart of a switch + std::size_t idx = p.length() - 2; + while (idx > 0) + { + if (positive_turn(p[idx], p[idx + 1]) == 1) + { + /// This is the end of a possible switchbale subpath + switchable[idx].flip(); + --idx; + while (idx > 0 && positive_turn(p[idx], p[idx + 1]) == 2) + { + switchable[idx].flip(); + --idx; + } + } else + { + --idx; + } + } + return switchable; + } + + /// Actually switch the dart in a vector of darts + void switch_dart(std::vector& p, std::size_t i, std::vector& switchable) const + { + CGAL_assertion(static_cast(switchable[i])); + p[i] = get_local_map().template beta<0, 2>(p[i]); + p[i + 1] = get_local_map().template beta<2, 0, 2>(p[i]); + switchable[i] = false; + /// It is guarantee that the last dart is not switchable + std::size_t j = i + 2; + for(; switchable[j - 1]; ++j) + { + p[j] = get_local_map().template beta<2, 0, 2, 0, 2>(p[j - 1]); + switchable[j - 1] = false; + } + /// Last dart may become switchable + if (j < p.size() && ((switchable[j] && positive_turn(p[j - 1], p[j]) == 2) || + positive_turn(p[j - 1], p[j]) == 1)) + { + switchable[j - 1] = true; + } + } + + /// Essentially compute the positive turn between ref and x + /// Requires x and ref outgoing at the same vertex + size_type get_order_relative_to(Dart_const_handle x, Dart_const_handle ref) const + { + CGAL_assertion(get_local_map().template belong_to_same_cell<0>(get_local_map().opposite2(x), ref)); +#if defined(CGAL_PWRLE_TURN_V2) || defined(CGAL_PWRLE_TURN_V3) + size_type ref_degree = get_local_map().template info<0>(ref); + size_type x_order = get_dart_id(get_local_map().opposite2(x)) % ref_degree; + size_type base_order = get_dart_id(ref) % ref_degree; + return (x_order < base_order) ? (x_order + ref_degree - base_order) : (x_order - base_order); +#else + return get_local_map().negative_turn(x, ref); +#endif + } + + /// Extend p[i] towards the reverse direction of ref + /// Requires p[i] and ref on the same 1-cell + /// @return the index + int get_previous_idx_relative_to(const std::vector& p, std::size_t i, Dart_const_handle ref) const + { + CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); + return p[i] == ref ? (static_cast(i) - 1) : (static_cast(i) + 1); + } + + /// Extend p[i] towards the reverse direction of ref + /// Requires p[i] and ref on the same 1-cell + /// @return whether the extension is viable without crossing the first and the last dart + bool has_previous_relative_to(const std::vector& p, std::size_t i, Dart_const_handle ref) const + { + CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); + int j = get_previous_idx_relative_to(p, i, ref); + return j >= 0 && j < p.size(); + } + + /// Extend p[i] towards the reverse direction of ref + /// Requires p[i] and ref on the same 1-cell + /// @return the actual dart, wrap around if reaching boundary + Dart_const_handle get_previous_relative_to(const std::vector& p, std::size_t i, Dart_const_handle ref) const + { + CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); + if (p[i] == ref) + { + return p[(i == 0) ? (p.size() - 1) : i - 1]; + } + else + { + return get_local_map().opposite2(p[(i == p.size() - 1) ? 0 : i + 1]); + } + } + + /// Extend p[i] towards the direction of ref + /// Requires p[i] and ref on the same 1-cell + /// @return the index + int get_next_idx_relative_to(const std::vector& p, std::size_t i, Dart_const_handle ref) const + { + CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); + return p[i] == ref ? (static_cast(i) + 1) : (static_cast(i) - 1); + } + + /// Extend p[i] towards the direction of ref + /// Requires p[i] and ref on the same 1-cell + /// @return whether the extension is viable without crossing the first and the last dart + bool has_next_relative_to(const std::vector& p, std::size_t i, Dart_const_handle ref) const + { + CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); + int j = get_next_idx_relative_to(p, i, ref); + return j >= 0 && j < static_cast(p.size()); + } + + /// Extend p[i] towards the direction of ref + /// Requires p[i] and ref on the same 1-cell + /// @return the actual dart, wrap around if reaching boundary + Dart_const_handle get_next_relative_to(const std::vector& p, std::size_t i, Dart_const_handle ref) const + { + CGAL_assertion(get_local_map().template belong_to_same_cell<1>(p[i], ref)); + if (p[i] == ref) + { + return p[(i == p.size() - 1) ? 0 : i + 1]; + } + else + { + return get_local_map().opposite2(p[(i == 0) ? (p.size() - 1) : i - 1]); + } + } + + /// @return a unique 1-cell id for the dart + size_type get_absolute_idx(Dart_const_handle dh) const + { + return (std::min)(get_local_map().darts().index(dh), get_local_map().darts().index(get_local_map().opposite(dh))); + } + + /// @return true if the dart is the representative for the unique 1-cell id + bool is_absolutely_directed(Dart_const_handle dh) const + { + return get_local_map().darts().index(dh) < get_local_map().darts().index(get_local_map().opposite(dh)); + } + + /// @return true if p[ref] -> p[ref + 1] forms the same corner as p[j] + /// Requires p[j] and p[ref] on the same 1-cell + bool is_same_corner(const std::vector& p, std::size_t j, std::size_t ref) const + { + if (!has_next_relative_to(p, j, p[ref])) + { + return false; + } + return get_next_relative_to(p, j, p[ref]) == p[ref + 1]; + } + protected: /// The original map (the mesh seen as a 2-map) const typename Get_map::storage_type m_original_map; diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h index 6b2ad7c3495..34ca3e55ecc 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h @@ -170,15 +170,15 @@ public: if (apath.is_closed()) { - if (!use_only_negative && apath.next_positive_turn(i)==2) + if (!use_only_negative && apath.prev_positive_turn(i)==2) { positive_flat=true; negative_flat=false; } - else if (!use_only_positive && apath.next_negative_turn(i)==2) + else if (!use_only_positive && apath.prev_negative_turn(i)==2) { positive_flat=false; negative_flat=true; } - while ((positive_flat && apath.next_positive_turn(i)==2) || - (negative_flat && apath.next_negative_turn(i)==2)) + while ((positive_flat && apath.prev_positive_turn(i)==2) || + (negative_flat && apath.prev_negative_turn(i)==2)) { - i=apath.next_index(i); + i=apath.prev_index(i); if (i==0) // Case of a closed path, made of only one flat part. { m_path.push_back(Flat(apath.real_front(), apath.real_back(), @@ -189,8 +189,7 @@ public: return; } } - // Here i is the last dart of a flat - i=apath.next_index(i); // Now we are sure that i is the beginning of a flat + // Here i is the first dart of a flat } starti=i; @@ -1217,6 +1216,15 @@ public: return is_next_flat_can_be_extended_at_beginning(it, dh, dummy1, dummy2); } + /// @return true iff the flat 'it' forms a switchable subpath (aka left-L-shape) + bool is_switchable(const List_iterator& it) + { + CGAL_assertion(is_valid_iterator(it)); + if (it == m_path.begin() || std::next(it) == m_path.end()) { return false; } + std::size_t t=next_positive_turn(it); + return (t==1 && flat_length(it) >= 0); + } + /// Add the given dart 'dh' before the flat 'it'. void add_dart_before(const List_iterator& it, Dart_const_handle dh, Set_of_it& modified_flats) diff --git a/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt b/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt index 070c7327bcd..dd5836f3dfb 100644 --- a/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt +++ b/Surface_mesh_topology/test/Surface_mesh_topology/CMakeLists.txt @@ -21,19 +21,25 @@ endif() # add_definitions("-D_GLIBCXX_DEBUG") set(SOURCE_FILES - fundamental_group_of_the_circle.cpp - fundamental_group_of_the_torus.cpp - homotopy_big_cylinder.cpp - homotopy_double_torus_with_holes.cpp - homotopy_rond_point_saucisse.cpp - homotopy_small_cylinder.cpp - path_tests.cpp - path_with_rle_deformation_tests.cpp - shortest_noncontractible_cycle_tests.cpp - test_homotopy.cpp - test_homotopy_with_polygonal_schema.cpp - test_shortest_cycle_non_contractible.cpp - tests_path_on_surface.cpp) + fundamental_group_of_the_circle.cpp + fundamental_group_of_the_torus.cpp + homotopy_big_cylinder.cpp + homotopy_double_torus_with_holes.cpp + homotopy_rond_point_saucisse.cpp + homotopy_small_cylinder.cpp + path_tests.cpp + path_with_rle_deformation_tests.cpp + shortest_noncontractible_cycle_tests.cpp + simplicity_cylinder.cpp + simplicity_double_torus.cpp + simplicity_double_torus_with_holes.cpp + simplicity_fundamental_polygon.cpp + simplicity_torus.cpp + test_homotopy.cpp + test_homotopy_with_polygonal_schema.cpp + test_shortest_cycle_non_contractible.cpp + tests_path_on_surface.cpp + ) foreach(cppfile ${SOURCE_FILES}) create_single_source_cgal_program("${cppfile}") diff --git a/Surface_mesh_topology/test/Surface_mesh_topology/path_tests.cpp b/Surface_mesh_topology/test/Surface_mesh_topology/path_tests.cpp index ee9e5ba0765..28cbe41a528 100644 --- a/Surface_mesh_topology/test/Surface_mesh_topology/path_tests.cpp +++ b/Surface_mesh_topology/test/Surface_mesh_topology/path_tests.cpp @@ -93,9 +93,9 @@ bool basic_tests() internal::Light_MQ lmq(p6.get_map()); internal::Path_on_surface_with_rle > p7(lmq, p6); - if (!p7.is_valid() || p7.size_of_list()!=2) + if (!p7.is_valid() || p7.size_of_list()!=3) { - std::cerr<<"path_tests ERROR: !p7.is_valid() || size_of_list()!=2."< +#include +#include + +using namespace CGAL::Surface_mesh_topology; +typedef Polygonal_schema_with_combinatorial_map<> PS; + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh_1(PS& ps) +{ + ps.add_facet("a b c d"); + ps.add_facet("-b e -d f"); + ps.add_facet("-a -e"); + ps.add_facet("-c -f"); + ps.perforate_facet("-a"); + ps.perforate_facet("-c"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh_2(PS& ps) +{ + ps.add_facet("a b c d"); + ps.add_facet("-b e -d f"); + ps.add_facet("-a -e"); + ps.add_facet("-c -f"); + ps.perforate_facet("-a"); + ps.perforate_facet("-c"); + ps.perforate_facet("a"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh_3(PS& ps) +{ + ps.add_facet("a b c d"); + ps.add_facet("-b e -d f"); + ps.add_facet("-a -e"); + ps.add_facet("-c -f"); + ps.perforate_facet("-a"); + ps.perforate_facet("-c"); + ps.perforate_facet("e"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_1(Path_on_surface& p) +{ + p.push_back_by_label("a e"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_2(Path_on_surface& p) +{ + p.push_back_by_label("a b -f d a e"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_3(Path_on_surface& p) +{ + p.push_back_by_label("a b c d"); +} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + PS ps[2]; + create_mesh_1(ps[0]); + create_mesh_2(ps[1]); + + std::size_t num_ps = sizeof(ps) / sizeof(PS); + bool res=true; + + for(std::size_t i = 0; i < num_ps; ++i) + { + Curves_on_surface_topology cst(ps[i]); + Path_on_surface p1(ps[i]), p2(ps[i]), p3(ps[i]); + create_path_1(p1); + create_path_2(p2); + create_path_3(p3); + + if(!cst.is_homotopic_to_simple_cycle(p1)) + { + std::cout<<"ERROR simplicity_cylinder surface" + << (i+1) << "/test1: " + <<"Path p1 should be homotopic to a simple cycle" + < +#include +#include + +using namespace CGAL::Surface_mesh_topology; +typedef Polygonal_schema_with_combinatorial_map<> PS; + +/////////////////////////////////////////////////////////////////////////////// +void create_path_1(Path_on_surface& p) +{ + p.push_back_by_label("b b a b -d -d -d -c -d a"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_2(Path_on_surface& p) +{ + p.push_back_by_label("b b a b d c d d d a"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_3(Path_on_surface& p) +{ + p.push_back_by_label("a b b b a b b a b b"); + p.push_back_by_label("d c"); + p.push_back_by_label("d c d c d"); + p.push_back_by_label("-c -d"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_4(Path_on_surface& p) +{ + p.push_back_by_label("a b b b a b b a b b"); + p.push_back_by_label("d c"); + p.push_back_by_label("-d -c -d -c -d"); + p.push_back_by_label("-c -d"); +} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + PS ps; + ps.add_facet("a b -a -b c d -c -d"); + + Curves_on_surface_topology cst(ps); + Path_on_surface p1(ps), p2(ps), p3(ps), p4(ps); + create_path_1(p1); + create_path_2(p2); + create_path_3(p3); + create_path_4(p4); + + bool res=true; + + if(!cst.is_homotopic_to_simple_cycle(p1)) + { + std::cout<<"ERROR simplicity_double_torus test1: " + <<"Path p1 should be homotopic to a simple cycle" + < +#include +#include + +using namespace CGAL::Surface_mesh_topology; +typedef Polygonal_schema_with_combinatorial_map<> PS; + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh_1(PS& ps) +{ + ps.add_facet("b -a g f e"); + ps.add_facet("-b k i -g"); + ps.add_facet("-f -i -h"); + ps.add_facet("a -e h j"); + ps.add_facet("-k -m -l -j"); + ps.add_facet("c -r o m"); + ps.add_facet("-o -p -n"); + ps.add_facet("-d l n -q"); + ps.add_facet("d -c q p r"); + ps.perforate_facet("-i"); + ps.perforate_facet("-o"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh_2(PS& ps) +{ + ps.add_facet("a b -a -b o"); + ps.add_facet("-o -p"); + ps.add_facet("c d -c -d p"); + ps.perforate_facet("-o"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh_3(PS& ps) +{ + ps.add_facet("a b -a -b s"); + ps.add_facet("c d -c -d -s"); + ps.perforate_facet("s"); + ps.perforate_facet("-s"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_1(Path_on_surface& p) +{ + p.push_back_by_label("b b a b -d -d -d -c -d a"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_2(Path_on_surface& p) +{ + p.push_back_by_label("b b a b d c d d d a"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_3(Path_on_surface& p) +{ + p.push_back_by_label("a b b b a b b a b b"); + p.push_back_by_label("d c"); + p.push_back_by_label("d c d c d"); + p.push_back_by_label("-c -d"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_4(Path_on_surface& p) +{ + p.push_back_by_label("a b b b a b b a b b"); + p.push_back_by_label("d c"); + p.push_back_by_label("-d -c -d -c -d"); + p.push_back_by_label("-c -d"); +} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + PS ps[3]; + create_mesh_1(ps[0]); + create_mesh_2(ps[1]); + create_mesh_3(ps[2]); + + std::size_t num_ps = sizeof(ps) / sizeof(PS); + bool res=true; + + for(std::size_t i = 0; i < num_ps; ++i) + { + Curves_on_surface_topology cst(ps[i]); + Path_on_surface p1(ps[i]), p2(ps[i]), p3(ps[i]), p4(ps[i]); + create_path_1(p1); + create_path_2(p2); + create_path_3(p3); + create_path_4(p4); + + if(!cst.is_homotopic_to_simple_cycle(p1)) + { + std::cout<<"ERROR simplicity_double_torus_with_holes surface" + << (i+1) << "/test1: " + <<"Path p1 should be homotopic to a simple cycle" + < +#include +#include + +using namespace CGAL::Surface_mesh_topology; +typedef Polygonal_schema_with_combinatorial_map<> PS; + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh1(PS& ps) +{ + ps.add_facet("a b -a -b c d -c -d"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh1_path1(Path_on_surface& p) +{ + p.push_back_by_label("a b c c -a -a -a b"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh1_path2(Path_on_surface& p) +{ + p.push_back_by_label("a c a a c -a"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh1_path3(Path_on_surface& p) +{ + p.push_back_by_label("d -c a a b a d b -c -c d b"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh2(PS& ps) +{ + ps.add_facet("a b -a -b c d -c -d e f -e -f"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh2_path1(Path_on_surface& p) +{ + p.push_back_by_label("b -c e -f c -f c b e c"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh2_path2(Path_on_surface& p) +{ + p.push_back_by_label("a f -e a -e f"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_mesh2_path3(Path_on_surface& p) +{ + p.push_back_by_label("f a f -b -e -e b a"); +} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + PS ps1, ps2; + create_mesh1(ps1); + create_mesh2(ps2); + + bool res=true; + + Curves_on_surface_topology cst1(ps1), cst2(ps2); + Path_on_surface p1_1(ps1), p2_1(ps1), p3_1(ps1), + p1_2(ps2), p2_2(ps2), p3_2(ps2); + + create_mesh1_path1(p1_1); + create_mesh1_path2(p2_1); + create_mesh1_path3(p3_1); + create_mesh2_path1(p1_2); + create_mesh2_path2(p2_2); + create_mesh2_path3(p3_2); + + if(cst1.is_homotopic_to_simple_cycle(p1_1)) + { + std::cout<<"ERROR simplicity_homology_group test1" + <<"Path p1_1 should not be homotopic to a simple cycle" + < +#include +#include + +using namespace CGAL::Surface_mesh_topology; +typedef Polygonal_schema_with_combinatorial_map<> PS; + +/////////////////////////////////////////////////////////////////////////////// +void create_path_1(Path_on_surface& p) +{ + p.push_back_by_label("a b a a b"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_2(Path_on_surface& p) +{ + p.push_back_by_label("a b"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_3(Path_on_surface& p) +{ + p.push_back_by_label("-a b a b b"); +} + +/////////////////////////////////////////////////////////////////////////////// +void create_path_4(Path_on_surface& p) +{ + p.push_back_by_label("-a -b a a -b -b a a -b a -b -b"); +} + +/////////////////////////////////////////////////////////////////////////////// +int main() +{ + PS ps; + ps.add_facet("a b -a -b"); + + Curves_on_surface_topology cst(ps); + Path_on_surface p1(ps), p2(ps), p3(ps), p4(ps); + create_path_1(p1); + create_path_2(p2); + create_path_3(p3); + create_path_4(p4); + + bool res=true; + + if(!cst.is_homotopic_to_simple_cycle(p1)) + { + std::cout<<"ERROR simplicity_torus test1: " + <<"Path p1 should be homotopic to a simple cycle" + < -#include - -#include - -namespace CGAL { -namespace Total { -namespace internal { - -//To avoid "fopen may be unsafe" on Visual. -bool open_file(FILE **fin, const char* filename) -{ -#if defined(BOOST_MSVC) - return (fopen_s(fin, filename, "rw") == 0); -#else - *fin = fopen(filename, "rw"); - return (fin != NULL); -#endif -} - -} // namespace internal - -void permuteLong(char *a) -{ - char tmp; - -#ifdef CGAL_LITTLE_ENDIAN -tmp=a[0]; a[0]=a[3]; a[3]=tmp; -tmp=a[1]; a[1]=a[2]; a[2]=tmp; -#endif -} - -void permuteLongTab(long *a,int nb) -{ - int i; - -#ifdef CGAL_LITTLE_ENDIAN -for(i=0;isetNum((int)image_word_size() * - dim_x->value() * - dim_y->value() * - dim_z->value()); -} - -unsigned int Raw_image_dialog::image_word_size() const { - if(short_bt->isChecked()) - return 2; - if(int_bt->isChecked()) - return 4; - else if(float_bt->isChecked()) - return 4; - else if(double_bt->isChecked()) - return 8; - else - return 1; -} - diff --git a/Surface_mesher/demo/Surface_mesher/Raw_image_dialog.h b/Surface_mesher/demo/Surface_mesher/Raw_image_dialog.h deleted file mode 100644 index 7f191fecaf6..00000000000 --- a/Surface_mesher/demo/Surface_mesher/Raw_image_dialog.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef RAW_IMAGE_DIALOG_H -#define RAW_IMAGE_DIALOG_H - -#include "ui_raw_image.h" - -class Raw_image_dialog : public QDialog, public Ui::Raw_image_dialog -{ - Q_OBJECT - -public: - Raw_image_dialog(QWidget* parent = 0); - - unsigned int image_word_size() const; - -private Q_SLOTS: - void update_image_size(); -}; - -#endif // RAW_IMAGE_DIALOG diff --git a/Surface_mesher/demo/Surface_mesher/Surface_mesher.cpp b/Surface_mesher/demo/Surface_mesher/Surface_mesher.cpp deleted file mode 100644 index b6c18695ab5..00000000000 --- a/Surface_mesher/demo/Surface_mesher/Surface_mesher.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include "mainwindow.h" -#include -#include -#include - -int main(int argc, char** argv) -{ - QApplication application(argc,argv); - - application.setOrganizationDomain("geometryfactory.com"); - application.setOrganizationName("GeometryFactory"); - application.setApplicationName("Surface mesher Qt5 demo"); - - MainWindow w; - - if(argc>1) - w.surface_open(argv[1]); - - w.show(); - std::setlocale(LC_ALL, "C"); - return application.exec(); - std::cerr << "Exit\n"; -} diff --git a/Surface_mesher/demo/Surface_mesher/binary_image.h b/Surface_mesher/demo/Surface_mesher/binary_image.h deleted file mode 100644 index 591e6159744..00000000000 --- a/Surface_mesher/demo/Surface_mesher/binary_image.h +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright (c) 2005-2008 INRIA Sophia-Antipolis (France). -// Copyright (c) 2008 GeometryFactory (France) -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org). -// -// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial -// -// Author(s) : Laurent RINEAU, Pierre ALLIEZ - -#ifndef BINARY_IMAGE_3 -#define BINARY_IMAGE_3 - -#include - -#include -#include -#include - -#include -#include - -#include - -#include - -template -class CBinary_image_3 : public CGAL::Image_3 -{ - bool interpolate_; - bool labellized_; - -public: - double min_value; - double max_value; - - typedef FT_ FT; - -public: - CBinary_image_3() - : Image_3(), interpolate_(true) - { - } - - CBinary_image_3(const Image_3& bi) - : Image_3(bi), interpolate_(true) - { - } - - - CBinary_image_3(const CBinary_image_3& bi) - : Image_3(bi), interpolate_(bi.interpolate_),labellized_(bi.labellized_) - { - std::cerr << "CBinary_image_3::copy_constructor\n"; - min_value = bi.min_value; - max_value = bi.max_value; - } - - - void finish_open() { - CGAL_IMAGE_IO_CASE(image_ptr.get(), - Word *min; Word *max; - (boost::tie(min, max)) = - (CGAL::min_max_element((Word*)(data()), - (Word*)(data()) + - xdim() * ydim() * zdim())); - min_value = *min; - max_value = *max;) - } - - float xmax() const - { - return (float)(((image_ptr->xdim) - 1.0)*(image_ptr->vx)); - } - - float ymax() const - { - return (float)(((image_ptr->ydim) - 1.0)*(image_ptr->vy)); - } - - float zmax() const - { - return (float)(((image_ptr->zdim) - 1.0)*(image_ptr->vz)); - } - - Point center() - { - FT cx = 0.5 * xmax(); - FT cy = 0.5 * ymax(); - FT cz = 0.5 * zmax(); - return Point(cx,cy,cz); - } - - FT radius() - { - return (std::max)((std::max)(xmax(),ymax()),zmax()); - } - - Point point(const std::size_t i, - const std::size_t j, - const std::size_t k) const - { - return Point(i * (image_ptr->vx), - j * (image_ptr->vy), - k * (image_ptr->vz)); - } - -public: - bool inside(const float x, - const float y, - const float z) const - { - return ( x >= 0.0f && - y >= 0.0f && - z >= 0.0f && - x <= xmax() && - y <= ymax() && - z <= zmax() ); - } - - float rand_x() { return (float)rand() / (float)RAND_MAX * xmax(); } - float rand_y() { return (float)rand() / (float)RAND_MAX * ymax(); } - float rand_z() { return (float)rand() / (float)RAND_MAX * zmax(); } - - void set_interpolation(const bool b) - { - interpolate_ = b; - } - - bool interpolation() const { - return interpolate_; - } - - void set_labellized(const bool b) - { - labellized_ = b; - } - - bool labellized() const { - return labellized_; - } - - FT operator()(Point p) const - { - const float x = static_cast(CGAL::to_double(p.x())); - const float y = static_cast(CGAL::to_double(p.y())); - const float z = static_cast(CGAL::to_double(p.z())); - - if(interpolation()) { - if(labellized()) { - CGAL_IMAGE_IO_CASE(image_ptr.get(), - return (this->labellized_trilinear_interpolation(x, y, z, min_value));) - } - else { - CGAL_IMAGE_IO_CASE(image_ptr.get(), - return (this->trilinear_interpolation(x, y, z, min_value));) - } - } - else { - const std::ptrdiff_t i = static_cast(x/image()->vx + 0.5f); - const std::ptrdiff_t j = static_cast(y/image()->vy + 0.5f); - const std::ptrdiff_t k = static_cast(z/image()->vz + 0.5f); - if( i < 0 || - j < 0 || - k < 0 ) - { - return 0; - } - else - { - const std::size_t ui = static_cast(i); - const std::size_t uj = static_cast(j); - const std::size_t uk = static_cast(k); - if( ui >= image()->xdim || - uj >= image()->ydim || - uk >= image()->zdim ) - { - return 0; - } - else - { - return this->value(ui, uj, uk); - } - } - } - return FT(); - } -}; // end CBinary_image_3 - -#endif // BINARY_IMAGE_3 diff --git a/Surface_mesher/demo/Surface_mesher/colorlisteditor.cpp b/Surface_mesher/demo/Surface_mesher/colorlisteditor.cpp deleted file mode 100644 index 508b532c090..00000000000 --- a/Surface_mesher/demo/Surface_mesher/colorlisteditor.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2007-2007 Trolltech ASA. All rights reserved. -** -** This file is part of the example classes of the Qt Toolkit. -** -** This file may be used under the terms of the GNU General Public -** License version 2.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/ -** -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.0, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** In addition, as a special exception, Trolltech, as the sole copyright -** holder for Qt Designer, grants users of the Qt/Eclipse Integration -** plug-in the right for the Qt/Eclipse Integration to link to -** functionality provided by Qt Designer and its related libraries. -** -** Trolltech reserves all rights not expressly granted herein. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -** SPDX-License-Identifier: LGPL-2.0-only -** -****************************************************************************/ - -#include - -#include "colorlisteditor.h" - -ColorListEditor::ColorListEditor(QWidget *widget) : QComboBox(widget) -{ - populateList(); -} - -QColor ColorListEditor::color() const -{ - return itemData(currentIndex(), Qt::DecorationRole).value(); -} - -void ColorListEditor::setColor(QColor color) -{ - setCurrentIndex(findData(color, int(Qt::DecorationRole))); -} - -void ColorListEditor::populateList() -{ - QStringList colorNames = QColor::colorNames(); - - for (int i = 0; i < colorNames.size(); ++i) { - QColor color(colorNames[i]); - - insertItem(i, colorNames[i]); - setItemData(i, color, Qt::DecorationRole); - } -} - diff --git a/Surface_mesher/demo/Surface_mesher/colorlisteditor.h b/Surface_mesher/demo/Surface_mesher/colorlisteditor.h deleted file mode 100644 index 4763d52b3b0..00000000000 --- a/Surface_mesher/demo/Surface_mesher/colorlisteditor.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2007-2007 Trolltech ASA. All rights reserved. -** -** This file is part of the example classes of the Qt Toolkit. -** -** This file may be used under the terms of the GNU General Public -** License version 2.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/ -** -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.0, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** In addition, as a special exception, Trolltech, as the sole copyright -** holder for Qt Designer, grants users of the Qt/Eclipse Integration -** plug-in the right for the Qt/Eclipse Integration to link to -** functionality provided by Qt Designer and its related libraries. -** -** Trolltech reserves all rights not expressly granted herein. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -** SPDX-License-Identifier: LGPL-2.0-only -** -****************************************************************************/ - -#ifndef COLORLISTEDITOR_H -#define COLORLISTEDITOR_H - -#include - -class QColor; -class QWidget; - -class ColorListEditor : public QComboBox -{ - Q_OBJECT - Q_PROPERTY(QColor color READ color WRITE setColor USER true) - -public: - ColorListEditor(QWidget *widget = 0); - -public: - QColor color() const; - void setColor(QColor c); - -private: - void populateList(); -}; - -#endif diff --git a/Surface_mesher/demo/Surface_mesher/get_polyhedral_surface.h b/Surface_mesher/demo/Surface_mesher/get_polyhedral_surface.h deleted file mode 100644 index 51ebed3272d..00000000000 --- a/Surface_mesher/demo/Surface_mesher/get_polyhedral_surface.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _GET_POLYHEDRAL_SURFACE_H -#define _GET_POLYHEDRAL_SURFACE_H - -#include "surface.h" - -Surface* get_polyhedral_surface(QObject*, double, double); - -#endif // _GET_POLYHEDRAL_SURFACE_H diff --git a/Surface_mesher/demo/Surface_mesher/icons/bbox-red.png b/Surface_mesher/demo/Surface_mesher/icons/bbox-red.png deleted file mode 100644 index 0da5c8fdde3..00000000000 Binary files a/Surface_mesher/demo/Surface_mesher/icons/bbox-red.png and /dev/null differ diff --git a/Surface_mesher/demo/Surface_mesher/icons/bbox-red.svg b/Surface_mesher/demo/Surface_mesher/icons/bbox-red.svg deleted file mode 100644 index 25be024f77e..00000000000 --- a/Surface_mesher/demo/Surface_mesher/icons/bbox-red.svg +++ /dev/null @@ -1,209 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - diff --git a/Surface_mesher/demo/Surface_mesher/icons/bbox.png b/Surface_mesher/demo/Surface_mesher/icons/bbox.png deleted file mode 100644 index 28c0d50c6b3..00000000000 Binary files a/Surface_mesher/demo/Surface_mesher/icons/bbox.png and /dev/null differ diff --git a/Surface_mesher/demo/Surface_mesher/icons/bbox.svg b/Surface_mesher/demo/Surface_mesher/icons/bbox.svg deleted file mode 100644 index e23b746c510..00000000000 --- a/Surface_mesher/demo/Surface_mesher/icons/bbox.svg +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/Surface_mesher/demo/Surface_mesher/icons/cgal_logo.xpm b/Surface_mesher/demo/Surface_mesher/icons/cgal_logo.xpm deleted file mode 100644 index 6a69b3d67e1..00000000000 --- a/Surface_mesher/demo/Surface_mesher/icons/cgal_logo.xpm +++ /dev/null @@ -1,24 +0,0 @@ -/* XPM */ -const char * demoicon_xpm[] = { -/* columns rows colors chars-per-pixel */ -"16 16 3 1", -" c None", -". c #FFFF00", -"+ c #000000", -/* pixels */ -"................", -"...++++...++++..", -"..+....+.+....+.", -"..+......+......", -"..+......+..+++.", -"..+......+....+.", -"..+....+.+....+.", -"...++++...++++..", -"................", -"...++++...+.....", -"..+....+..+.....", -"..+....+..+.....", -"..++++++..+.....", -"..+....+..+.....", -"..+....+..+++++.", -"................"}; diff --git a/Surface_mesher/demo/Surface_mesher/icons/fileopen.png b/Surface_mesher/demo/Surface_mesher/icons/fileopen.png deleted file mode 100644 index 82b79b7242b..00000000000 Binary files a/Surface_mesher/demo/Surface_mesher/icons/fileopen.png and /dev/null differ diff --git a/Surface_mesher/demo/Surface_mesher/icons/filesave.png b/Surface_mesher/demo/Surface_mesher/icons/filesave.png deleted file mode 100644 index 0c5a242bc58..00000000000 Binary files a/Surface_mesher/demo/Surface_mesher/icons/filesave.png and /dev/null differ diff --git a/Surface_mesher/demo/Surface_mesher/icons/flip.png b/Surface_mesher/demo/Surface_mesher/icons/flip.png deleted file mode 100644 index 3d28392a0f5..00000000000 Binary files a/Surface_mesher/demo/Surface_mesher/icons/flip.png and /dev/null differ diff --git a/Surface_mesher/demo/Surface_mesher/icons/flip.svg b/Surface_mesher/demo/Surface_mesher/icons/flip.svg deleted file mode 100644 index 293e82fc3a7..00000000000 --- a/Surface_mesher/demo/Surface_mesher/icons/flip.svg +++ /dev/null @@ -1,207 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - Jakub Steiner - - - http://jimmac.musichall.cz - - Go Next - - - go - next - right - arrow - pointer - > - - - - - - - - - - - - - - - - - - - - diff --git a/Surface_mesher/demo/Surface_mesher/icons/minus.png b/Surface_mesher/demo/Surface_mesher/icons/minus.png deleted file mode 100644 index d6f233d7399..00000000000 Binary files a/Surface_mesher/demo/Surface_mesher/icons/minus.png and /dev/null differ diff --git a/Surface_mesher/demo/Surface_mesher/icons/plus.png b/Surface_mesher/demo/Surface_mesher/icons/plus.png deleted file mode 100644 index 40df1134f84..00000000000 Binary files a/Surface_mesher/demo/Surface_mesher/icons/plus.png and /dev/null differ diff --git a/Surface_mesher/demo/Surface_mesher/icons/resize.png b/Surface_mesher/demo/Surface_mesher/icons/resize.png deleted file mode 100644 index b3d930f1d7b..00000000000 Binary files a/Surface_mesher/demo/Surface_mesher/icons/resize.png and /dev/null differ diff --git a/Surface_mesher/demo/Surface_mesher/icons/resize.svg b/Surface_mesher/demo/Surface_mesher/icons/resize.svg deleted file mode 100644 index ed30359a802..00000000000 --- a/Surface_mesher/demo/Surface_mesher/icons/resize.svg +++ /dev/null @@ -1,297 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Surface_mesher/demo/Surface_mesher/icons/surface.png b/Surface_mesher/demo/Surface_mesher/icons/surface.png deleted file mode 100644 index e3585c5d816..00000000000 Binary files a/Surface_mesher/demo/Surface_mesher/icons/surface.png and /dev/null differ diff --git a/Surface_mesher/demo/Surface_mesher/icons/surface.svg b/Surface_mesher/demo/Surface_mesher/icons/surface.svg deleted file mode 100644 index b3ce5b253a7..00000000000 --- a/Surface_mesher/demo/Surface_mesher/icons/surface.svg +++ /dev/null @@ -1,166 +0,0 @@ - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - diff --git a/Surface_mesher/demo/Surface_mesher/icons/twosides.png b/Surface_mesher/demo/Surface_mesher/icons/twosides.png deleted file mode 100644 index a2da1eb1b39..00000000000 Binary files a/Surface_mesher/demo/Surface_mesher/icons/twosides.png and /dev/null differ diff --git a/Surface_mesher/demo/Surface_mesher/icons/twosides.svg b/Surface_mesher/demo/Surface_mesher/icons/twosides.svg deleted file mode 100644 index e1effe1d026..00000000000 --- a/Surface_mesher/demo/Surface_mesher/icons/twosides.svg +++ /dev/null @@ -1,169 +0,0 @@ - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - Jakub Steiner - - - http://jimmac.musichall.cz - - Go Next - - - go - next - right - arrow - pointer - > - - - - - - - - - - - - - - - - - - - - diff --git a/Surface_mesher/demo/Surface_mesher/mainwindow.cpp b/Surface_mesher/demo/Surface_mesher/mainwindow.cpp deleted file mode 100644 index ebb1260a693..00000000000 --- a/Surface_mesher/demo/Surface_mesher/mainwindow.cpp +++ /dev/null @@ -1,179 +0,0 @@ -#include "mainwindow.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include // std::max -#include // std::sqrt -#include - -#include "ui_mainwindow.h" -#include "volume.h" -#ifndef CGAL_DO_NOT_USE_POLYHEDRAL_SURFACE -# include "polyhedral_surface.h" -#endif - -MainWindow::MainWindow(MainWindow* other_window /* = 0 */) : - CGAL::Qt::DemosMainWindow(), - surface(0) -{ - setupUi(this); - setAcceptDrops(true); - - if(other_window != 0) - { - viewer->setCamera(other_window->viewer->camera()); - connect(other_window, SIGNAL(destroyed()), - this, SLOT(close())); - } - - this->addAboutCGAL(); - this->addRecentFiles(this->menu_File, - this->action_Quit); - connect(this, SIGNAL(openRecentFile(QString)), - this, SLOT(surface_open(QString))); - - this->readState(); - - show_only(""); -} - -void MainWindow::dragEnterEvent(QDragEnterEvent *event) -{ - if (event->mimeData()->hasFormat("text/uri-list")) - event->acceptProposedAction(); -} - -void MainWindow::dropEvent(QDropEvent *event) -{ - QString filename = event->mimeData()->urls().at(0).toLocalFile(); - surface_open(filename); - event->acceptProposedAction(); -} - -void MainWindow::surface_open(const QString& filename) -{ - if(surface != 0) { - delete surface; - surface = 0; - } -#ifndef CGAL_DO_NOT_USE_POLYHEDRAL_SURFACE - surface = new Polyhedral_surface(this); - if(surface->open(filename)) { - this->addToRecentFiles(filename); - return; - } - delete surface; - surface = 0; -#endif - surface = new Volume(this); - if(surface->open(filename)) { - this->addToRecentFiles(filename); - } -} - -void MainWindow::show_only(QString tag) -{ -#if 0 - QTextStream err(stderr); -#else - QString dummy; - QTextStream err(&dummy); -#endif - err << "** Show only in \"" << tag << "\"\n"; - Q_FOREACH(QObject* object, - this->findChildren()) - { - QStringList show_only_in = object->property("show_only_in").toStringList(); - if(!show_only_in.isEmpty()) - { - err << object->metaObject()->className() - << " \"" << object->objectName() << "\" only in: "; - Q_FOREACH(QString s, show_only_in) - err << s << " "; - const bool visible = show_only_in.contains(tag); - err << (visible ? "(enabled)\n" : "(disabled)\n"); - if(QMenu* menu = qobject_cast(object)) { - menu->menuAction()->setVisible(visible); - } - else { - object->setProperty("visible", QVariant::fromValue(visible)); - } - } - } -} - -void MainWindow::on_action_Open_triggered() -{ - QSettings settings; - QString directory = settings.value("Open directory", - QDir::current().dirName()).toString(); - QString filename = QFileDialog::getOpenFileName(this, tr("Open File"), - directory, - tr("all Files (*.*)")); - if(!filename.isEmpty()) { - QFileInfo fileinfo(filename); - if(fileinfo.isFile() && fileinfo.isReadable()) { - settings.setValue("Open directory", - fileinfo.absoluteDir().absolutePath()); - surface_open(filename); - } - } -} - -void MainWindow::on_action_OpenDirectory_triggered() -{ - QSettings settings; - QString start_dir = settings.value("Open directory", - QDir::current().dirName()).toString(); - QString dir = - QFileDialog::getExistingDirectory(this, - tr("Open directory"), - start_dir, - QFileDialog::ShowDirsOnly - | QFileDialog::DontResolveSymlinks); - - if (!dir.isEmpty()) { - QFileInfo fileinfo(dir); - if (fileinfo.isDir() && fileinfo.isReadable()) - { - settings.setValue("Open directory", - fileinfo.absoluteDir().absolutePath()); - surface_open(dir); - } - } -} - -void MainWindow::on_action_Quit_triggered() -{ - this->writeState(); - qApp->exit(); -} - -void MainWindow::closeEvent(QCloseEvent *event) -{ - this->writeState(); - event->accept(); -} - -void MainWindow::on_action_Clone_triggered() -{ - MainWindow* other = new MainWindow(this); - other->show(); -} - diff --git a/Surface_mesher/demo/Surface_mesher/mainwindow.h b/Surface_mesher/demo/Surface_mesher/mainwindow.h deleted file mode 100644 index 36aa2db2138..00000000000 --- a/Surface_mesher/demo/Surface_mesher/mainwindow.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef _MAINWINDOW_H -#define _MAINWINDOW_H - -#include -#include "ui_mainwindow.h" -#include - -class QDragEnterEvent; -class QDropEvent; -class Surface; -class QDoubleSpinBox; -class QCloseEvent; - -namespace CGAL{ -class QGLViewer; -} - -class MainWindow : public CGAL::Qt::DemosMainWindow, public Ui::MainWindow -{ - Q_OBJECT -public: - MainWindow(MainWindow* other_window = 0); - void dragEnterEvent(QDragEnterEvent *); - void dropEvent(QDropEvent *event); - -public Q_SLOTS: - void show_only(QString); - void surface_open(const QString& filename); - -private Q_SLOTS: - void on_action_Open_triggered(); - void on_action_OpenDirectory_triggered(); - void on_action_Quit_triggered(); - void on_action_Clone_triggered(); - -private: - void closeEvent(QCloseEvent *event); - Surface* surface; -}; - - -#endif // _MAINWINDOW_H diff --git a/Surface_mesher/demo/Surface_mesher/polyhedral_surface.cpp b/Surface_mesher/demo/Surface_mesher/polyhedral_surface.cpp deleted file mode 100644 index 2ac24c2b2c4..00000000000 --- a/Surface_mesher/demo/Surface_mesher/polyhedral_surface.cpp +++ /dev/null @@ -1,407 +0,0 @@ -#include "polyhedral_surface.h" -#include "get_polyhedral_surface.h" - -#include -#include -#include -#include -#include -#include -#include "ui_optionsdialog.h" -#include -#include -#include -#include -#include "mainwindow.h" - -typedef CGAL_polyhedral_surface::Polyhedron Polyhedron; - -Polyhedral_surface::Polyhedral_surface(QObject* parent, - double sharp_edges_angle_lower_bound, - double sharp_edges_angle_upper_bound) - : Surface(parent), - m_inverse_normals(false), - surface_ptr(0), - parent(parent), - display_octree(false), - display_edges_octree(false), - display_surface(true), - display_all_edges(true), - display_control_edges(false), - sharp_edges_angle_lower_bound(sharp_edges_angle_lower_bound), - sharp_edges_angle_upper_bound(sharp_edges_angle_upper_bound), - is_octree_initialized(false), - selected_edge(-1), - selected_facet(-1), - is_dirty(true), - list_id(0) -{ - connection_map["actionDisplay_octree"] = - std::make_pair(SIGNAL(toggled(bool)), - SLOT(toggle_display_octree(bool))); - - connection_map["actionDisplay_edges_octree"] = - std::make_pair(SIGNAL(toggled(bool)), - SLOT(toggle_display_edges_octree(bool))); - - connection_map["actionDisplay_surface"] = - std::make_pair(SIGNAL(toggled(bool)), - SLOT(toggle_display_surface(bool))); - - connection_map["actionDisplay_all_edges"] = - std::make_pair(SIGNAL(toggled(bool)), - SLOT(toggle_display_all_edges(bool))); - - connection_map["actionDisplay_control_edges"] = - std::make_pair(SIGNAL(toggled(bool)), - SLOT(toggle_display_control_edges(bool))); - - connection_map["actionInverse_normals"] = - std::make_pair(SIGNAL(toggled(bool)), - SLOT(set_inverse_normals(bool))); - - connection_map["actionSubdivision"] = - std::make_pair(SIGNAL(triggered()), - SLOT(make_one_subdivision_step())); - connection_map["action_Options"] = - std::make_pair(SIGNAL(triggered()), - SLOT(on_action_Options_triggered())); -} - -Polyhedral_surface::~Polyhedral_surface() -{ - clear(); - delete surface_ptr; -} - -void Polyhedral_surface::on_action_Options_triggered() -{ - QDialog *options_dialog = new QDialog(qobject_cast(parent)); - Ui::OptionDialog ui; - ui.setupUi(options_dialog); - - QDoubleSpinBox* sb_upper = options_dialog->findChild("angle_upper_bound"); - QDoubleSpinBox* sb_lower = options_dialog->findChild("angle_lower_bound"); - - if(!sb_lower || !sb_upper) - return; - - sb_lower->setValue(sharp_edges_angle_lower_bound); - sb_upper->setValue(sharp_edges_angle_upper_bound); - if(options_dialog->exec() == QDialog::Accepted) - { - sharp_edges_angle_upper_bound = sb_upper->value(); - sharp_edges_angle_lower_bound = sb_lower->value(); - set_sharp_edges_angle_bounds(sharp_edges_angle_lower_bound, - sharp_edges_angle_upper_bound); - } -} - -void Polyhedral_surface::clear() { - for(Connection_map::const_iterator - it = connection_map.begin(), - end = connection_map.end(); - it != end; - ++it) - { - QAction* action = parent->findChild(it->first); - action->setVisible(false); - } -} - -void Polyhedral_surface::connect_actions() -{ - for(Connection_map::const_iterator - it = connection_map.begin(), - end = connection_map.end(); - it != end; - ++it) - { - QAction* action = parent->findChild(it->first); - action->setVisible(true); - if(action) - connect(action, it->second.first, - this, it->second.second); - } - MainWindow* mw = qobject_cast(parent); - if(mw) { -// mw->fix_menus_visibility(); - mw->show_only("polyhedral"); - } - - - connect(this, SIGNAL(changed()), this, SLOT(display_nb_elements_in_status_bar())); -} - -void Polyhedral_surface::display_nb_elements_in_status_bar() const -{ - QMainWindow* mw = qobject_cast(parent); - if(surface_ptr && mw) - { - mw->statusBar()->showMessage(QString("%1 vertices. %2 edges. %3 facets.") - .arg(surface_ptr->size_of_vertices()) - .arg(surface_ptr->size_of_halfedges()/2) - .arg(surface_ptr->size_of_facets())); - } -} - -void Polyhedral_surface::set_dirty() -{ - is_dirty = true; - Q_EMIT changed(); -} - -void Polyhedral_surface::busy() const -{ - QMainWindow* mw = qobject_cast(parent); - if(mw) - { - mw->statusBar()->showMessage(QString("Constructing octree...")); - } - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); -} - -void Polyhedral_surface::not_busy() const -{ - QApplication::restoreOverrideCursor(); - QMainWindow* mw = qobject_cast(parent); - if(mw) - { - mw->statusBar()->clearMessage(); - } -} - -void Polyhedral_surface::set_sharp_edges_angle_bounds(const double lower_bound, - const double upper_bound) -{ - sharp_edges_angle_lower_bound = lower_bound; - sharp_edges_angle_upper_bound = upper_bound; - if(surface_ptr) { - surface_ptr->set_sharp_edges_angle_bounds(lower_bound, upper_bound); - surface_ptr->set_sharp_vertices_angle_bounds(lower_bound, upper_bound); - update_data_structures(); - Q_EMIT set_dirty(); - } -} - -void Polyhedral_surface::update_data_structures() -{ - surface_ptr->compute_sharp_edges_incidence_graph(); - if(display_octree || display_edges_octree) { - construct_octree(); - is_octree_initialized = true; - } - else - is_octree_initialized = false; -} - -void Polyhedral_surface::construct_octree() -{ - busy(); - surface_ptr->construct_octree(); - not_busy(); -} - -void Polyhedral_surface::toggle_display_octree(bool b) -{ - if(surface_ptr && b && !is_octree_initialized) { - is_octree_initialized = true; - construct_octree(); - } - display_octree = b; - Q_EMIT set_dirty(); -} - -void Polyhedral_surface::toggle_display_edges_octree(bool b) -{ - if(surface_ptr && b && !is_octree_initialized) { - is_octree_initialized = true; - construct_octree(); - } - display_edges_octree = b; - Q_EMIT set_dirty(); -} - -void Polyhedral_surface::toggle_display_surface(bool b) -{ - display_surface = b; - Q_EMIT set_dirty(); -} - -void Polyhedral_surface::toggle_display_all_edges(bool b) -{ - display_all_edges = b; - Q_EMIT set_dirty(); -} - -void Polyhedral_surface::toggle_display_control_edges(bool b) -{ - display_control_edges = b; - Q_EMIT set_dirty(); -} - -void Polyhedral_surface::make_one_subdivision_step() -{ - if(surface_ptr) - { - Polyhedron output; - CSubdivider_loop pw_loop_subdiviser; - - pw_loop_subdiviser.subdivide(*surface_ptr, output); - static_cast(*surface_ptr) = output; - surface_ptr->compute_normals(); - surface_ptr->compute_type(); - update_data_structures(); - Q_EMIT set_dirty(); - } -} - -bool Polyhedral_surface::open(const QString& filename) -{ - clear(); - - std::cerr << "Opening file \"" << qPrintable(filename) << "\"..."; - std::ifstream in(filename.toUtf8()); - if(!in) return false; - - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - - if(surface_ptr) - delete surface_ptr; - surface_ptr = new CGAL_polyhedral_surface(in, - sharp_edges_angle_lower_bound, - sharp_edges_angle_upper_bound, - false /*do not construct - octree*/); - if(!in) { - QApplication::restoreOverrideCursor(); - return false; - } - is_octree_initialized = false; - selected_facet = selected_edge = -1; - update_data_structures(); - - connect_actions(); - std::cerr << " Done.\n"; - QApplication::restoreOverrideCursor(); - float xmin, ymin, zmin, xmax, ymax, zmax; - get_bbox(xmin, ymin, zmin, xmax, ymax, zmax); - const float xcenter = (xmin + xmax) / 2; - const float ycenter = (ymin + ymax) / 2; - const float zcenter = (zmin + zmax) / 2; - const float xdelta = (-xmin + xmax); - const float ydelta = (-ymin + ymax); - const float zdelta = (-zmin + zmax); -// const float radius = std::max(std::max(xdelta, ydelta), zdelta) * std::sqrt(3.)/ 2.; - std::cerr << boost::format("Bounding box: xmin=%1%, ymin=%2%, zmin=%3%\n" - " xmax=%4%, ymax=%5%, zmax=%6%\n" - " center=(%7%, %8%, %9%)\n") - % xmin % ymin % zmin % xmax % ymax % zmax - % xcenter % ycenter % zcenter - << boost::format(" span=(%1%,%2%,%3%)\n") - % xdelta % ydelta % zdelta; - viewer->camera()->setSceneBoundingBox(CGAL::qglviewer::Vec(xmin, ymin, zmin), - CGAL::qglviewer::Vec(xmax, ymax, zmax)); - viewer->setBackgroundColor(Qt::white); - viewer->showEntireScene(); - - QAction* actionInverse_normals = qFindChild(this, "actionInverse_normals"); - if(actionInverse_normals) actionInverse_normals->setChecked(false); - Q_EMIT set_dirty(); - return true; -} - -void Polyhedral_surface::close() -{ - delete surface_ptr; - surface_ptr = 0; -} - -void Polyhedral_surface::draw() { - draw(false); -} - -void Polyhedral_surface::drawWithNames() { - draw(true); -} - -void Polyhedral_surface::postSelection(const QPoint&) -{ - if(!surface_ptr) return; - - selected_facet = selected_edge = -1; - - const int nb_vertices = surface_ptr->incidence_graph.vertices.size(); - const int nb_edges = surface_ptr->incidence_graph.edges.size(); - if(viewer->selectedName() >= nb_edges + nb_vertices) - selected_facet = viewer->selectedName() - nb_edges - nb_vertices; - else if(viewer->selectedName() >= nb_vertices) - selected_edge = viewer->selectedName() - nb_vertices; - - std::cerr << boost::format("post-selection.\n" - "selectedName()=%1%\n" - "selected edge=%2%\n" - "selected facet=%3%\n") - % viewer->selectedName() % selected_edge % selected_facet; - - Q_EMIT set_dirty(); -} - -void Polyhedral_surface::draw(bool with_names) -{ - if(!list_id) - { - std::cerr << "Generating OpenGL display list ID: "; - std::cerr << (list_id = ::glGenLists(1)) << "\n"; - } - if(!with_names) - { - if(is_dirty) - ::glNewList(list_id, GL_COMPILE_AND_EXECUTE); - else if(::glIsList(list_id)) - { - ::glCallList(list_id); - return; - } - else - std::cerr << "Call list (" << list_id << ")failed.\n"; - } -} -void Polyhedral_surface::get_bbox(float& xmin, float& ymin, float& zmin, - float& xmax, float& ymax, float& zmax) -{ - if(surface_ptr) { - xmin=surface_ptr->bbox().xmin(); - ymin=surface_ptr->bbox().ymin(); - ymin=surface_ptr->bbox().zmin(); - xmax=surface_ptr->bbox().xmax(); - ymax=surface_ptr->bbox().ymax(); - zmax=surface_ptr->bbox().zmax(); - } - else - { - xmin = ymin = zmin = 0.f; - xmax = ymax = zmax = 1.f; - } -} - -void Polyhedral_surface::set_inverse_normals(const bool b) { - m_inverse_normals = b; - set_dirty(); -} - -bool Polyhedral_surface::inverse_normals() const { - return m_inverse_normals; -} - - -Surface* get_polyhedral_surface(QObject* parent, - double sharp_edges_angle_lower_bound, - double sharp_edges_angle_upper_bound = 180.) -{ - return new Polyhedral_surface(parent, - sharp_edges_angle_lower_bound, - sharp_edges_angle_upper_bound); -} - -#include "polyhedral_surface.moc" diff --git a/Surface_mesher/demo/Surface_mesher/polyhedral_surface.h b/Surface_mesher/demo/Surface_mesher/polyhedral_surface.h deleted file mode 100644 index 001eaee5fd6..00000000000 --- a/Surface_mesher/demo/Surface_mesher/polyhedral_surface.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef _POLYHEDRAL_SURFACE_H -#define _POLYHEDRAL_SURFACE_H - -#define CGAL_SURFACE_MESHER_DEBUG_POLYHEDRAL_SURFACE_CONSTRUCTION - -#include "surface.h" -#include "viewer.h" - -#include -#include - -typedef std::pair Signal_slot_pair; -typedef std::map Connection_map; - -// CGAL -#include - -// kernel -#include - -// surface -#include - -// piece-wise loop subdivision -#include - -typedef CGAL::Exact_predicates_inexact_constructions_kernel Poly_kernel; -typedef Poly_kernel::FT FT; -typedef Poly_kernel::Point_3 Poly_point; -typedef Poly_kernel::Sphere_3 Sphere; -typedef Poly_kernel::Vector_3 Vector; -typedef Poly_kernel::Triangle_3 Triangle_3; - -typedef CGAL::Polyhedral_surface_3 CGAL_polyhedral_surface; - - -class Polyhedral_surface : public Surface -{ - Q_OBJECT; - -public: - Polyhedral_surface(QObject* parent, - double sharp_edges_angle_lower_bound = 90, - double sharp_edges_angle_upper_bound = 120); - - ~Polyhedral_surface(); -public Q_SLOTS: - void clear(); - void connect_actions(); - void display_nb_elements_in_status_bar() const; - void set_dirty(); - void busy() const; - void not_busy() const; - void set_sharp_edges_angle_bounds(const double lower_bound, - const double upper_bound); - void update_data_structures(); - void construct_octree(); - void toggle_display_octree(bool b); - void toggle_display_edges_octree(bool b); - void toggle_display_surface(bool b); - void toggle_display_all_edges(bool b); - void toggle_display_control_edges(bool b); - void make_one_subdivision_step(); - void on_action_Options_triggered(); - -public: - bool open(const QString& filename); - void close(); - void draw(); - void drawWithNames(); - void postSelection(const QPoint&); - void draw(bool with_names); - void get_bbox(float& xmin, float& ymin, float& zmin, - float& xmax, float& ymax, float& zmax); - -public Q_SLOTS: - void set_inverse_normals(const bool b); - -public: - bool inverse_normals() const; - -protected: - bool m_inverse_normals; - CGAL_polyhedral_surface* surface_ptr; - QObject* parent; - bool display_octree; - bool display_edges_octree; - bool display_surface; - bool display_all_edges; - bool display_control_edges; - double sharp_edges_angle_lower_bound; - double sharp_edges_angle_upper_bound; - bool is_octree_initialized; - int selected_edge; - int selected_facet; - bool is_dirty; - GLint list_id; - Connection_map connection_map; -}; - -#endif // _POLYHEDRAL_SURFACE_H diff --git a/Surface_mesher/demo/Surface_mesher/surface.h b/Surface_mesher/demo/Surface_mesher/surface.h deleted file mode 100644 index 62e4b597a24..00000000000 --- a/Surface_mesher/demo/Surface_mesher/surface.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _SURFACE_H -#define _SURFACE_H - -#include -#include -#include - -#include "viewer.h" - -class Surface : public QObject -{ - Q_OBJECT -protected: - Surface(QObject* parent) - { - viewer = parent->findChild("viewer"); - - if(viewer) - connect(this, SIGNAL(changed()), viewer, SLOT(updateGL())); - viewer->set_surface(this); - } -public Q_SLOTS: - virtual bool open(const QString& filename) = 0; - virtual void close() = 0; - virtual void draw() = 0; - virtual void get_bbox(float&, float&, float&, - float&, float&, float&) = 0; - virtual void drawWithNames() {}; - virtual void postSelection(const QPoint&) {}; -Q_SIGNALS: - void changed(); - -protected: - Viewer* viewer; -}; - -#endif // _SURFACE_H diff --git a/Surface_mesher/demo/Surface_mesher/surface_mesher.qrc b/Surface_mesher/demo/Surface_mesher/surface_mesher.qrc deleted file mode 100644 index 9592cad50a0..00000000000 --- a/Surface_mesher/demo/Surface_mesher/surface_mesher.qrc +++ /dev/null @@ -1,13 +0,0 @@ - - - icons/bbox-red.png - icons/bbox.png - icons/cgal_logo.xpm - icons/fileopen.png - icons/filesave.png - icons/flip.png - icons/resize.png - icons/surface.png - icons/twosides.png - - diff --git a/Surface_mesher/demo/Surface_mesher/ui/mainwindow.ui b/Surface_mesher/demo/Surface_mesher/ui/mainwindow.ui deleted file mode 100644 index 65b8a528fa8..00000000000 --- a/Surface_mesher/demo/Surface_mesher/ui/mainwindow.ui +++ /dev/null @@ -1,808 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 1147 - 648 - - - - CGAL Surface mesh generator - - - - :/icons/cgal_logo.xpm:/icons/cgal_logo.xpm - - - true - - - - - - - - 1 - 0 - - - - - - - - - - 0 - 0 - 1147 - 21 - - - - - &File - - - - - - - - - - - &Options - - - - volume - polyhedral - - - - - - - - - - - - - - - - - - - &Edit - - - - polyhedral - - - - - - - - - - - - Actions toolbar - - - Qt::AllToolBarAreas - - - TopToolBarArea - - - false - - - - - - - - - - - - - - - - true - - - Meshing toolbar - - - - volume - - - - TopToolBarArea - - - false - - - - - - - Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea - - - Images options - - - - volume - - - - 1 - - - - - - - - - - 0 - 0 - - - - &Image type - - - - volume - - - - - - - - 0 - 0 - - - - Grayscale image - - - true - - - - - - - - 0 - 0 - - - - Segmented image - - - - - - - - - - &Operations - - - - - - Trilinear interpolation - - - true - - - - - - - Search for seeds - - - true - - - - - - - - - - - 0 - 0 - - - - C&riteria - - - - volume - - - - - - - Manifold - - - - - - - Facets vertices have same index - - - - - - - - - &Sizing bound: - - - spinBox_radius_bound - - - - - - - 5 - - - 9999.989999999999782 - - - - - - - &Distance bound: - - - spinBox_distance_bound - - - - - - - 5 - - - 9999.989999999999782 - - - - - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 0 - - - - - - - - - - - 0 - 0 - - - - Image sub-domaines - - - - volume - - - - 1 - - - - - 10 - 10 - - - - - - - - 0 - 5 - - - - - volume - - - - - - - - - - - :/icons/fileopen.png:/icons/fileopen.png - - - &Open... - - - Ctrl+O - - - - - &Quit - - - Ctrl+Q - - - QAction::QuitRole - - - - - true - - - - :/icons/flip.png:/icons/flip.png - - - &Inverse normals - - - Flip - - - Ctrl+I - - - - volume - polyhedral - - - - - - true - - - - :/icons/bbox.png:/icons/bbox.png - - - Display oc&tree - - - Ctrl+T - - - - polyhedral - - - - - - true - - - true - - - - :/icons/surface.png:/icons/surface.png - - - Display &surface - - - - polyhedral - - - - - - &Options... - - - - polyhedral - - - - - - Piecewise-smooth &subdivision - - - Ctrl+S - - - - polyhedral - - - - - - true - - - true - - - Display &all edges - - - Ctrl+A - - - - polyhedral - - - - - - true - - - false - - - Display &control edges - - - Ctrl+C - - - - polyhedral - - - - - - true - - - - :/icons/bbox-red.png:/icons/bbox-red.png - - - Display edges octree - - - - polyhedral - - - - - - Marching &cubes - - - Marching &cubes - - - - volume - - - - - - Surface &mesher - - - Surface &mesher - - - - volume - - - - - - true - - - true - - - - :/icons/twosides.png:/icons/twosides.png - - - Display facets with &front and back - - - Two-sides - - - Ctrl+F - - - - volume - polyhedral - - - - - - Clone - - - - - true - - - false - - - - :/icons/resize.png:/icons/resize.png - - - Auto-&resize - - - Auto-&resize - - - Automaticaly zoom in or out when the object change. - - - Ctrl+S - - - - volume - polyhedral - - - - - - true - - - true - - - Draw triangles &edges - - - Draw triangles &edges - - - Ctrl+E - - - - volume - - - - - - true - - - false - - - Use &Gouraud shading (marching cube only) - - - Use &Gouraud shading - - - Use Gouraud shading to display the marching cubes. - - - Ctrl+G - - - - volume - - - - - - true - - - Show the whole &triangulation (surface mesher only) - - - Ctrl+T - - - - volume - - - - - - Choose the triangulation edges &color... - - - - volume - - - - - - - :/icons/filesave.png:/icons/filesave.png - - - Export surface mesh to OFF... - - - - volume - - - - - - true - - - true - - - - :/icons/bbox.png:/icons/bbox.png - - - Show the image &bounding box - - - Ctrl+B - - - - volume - - - - - - - :/icons/filesave.png:/icons/filesave.png - - - Save the image as Inrimage... - - - - - - :/icons/fileopen.png:/icons/fileopen.png - - - Open directory... - - - - - - Values_list - QWidget -
    values_list.h
    - 1 -
    - - Viewer - QWidget -
    viewer.h
    -
    -
    - - viewer - grayLevelRadioButton - labellizedRadioButton - manifoldCheckBox - sameIndexCheckBox - spinBox_radius_bound - spinBox_distance_bound - - - - - - - labellizedRadioButton - toggled(bool) - sameIndexCheckBox - setDisabled(bool) - - - 130 - 172 - - - 139 - 414 - - - - -
    diff --git a/Surface_mesher/demo/Surface_mesher/ui/optionsdialog.ui b/Surface_mesher/demo/Surface_mesher/ui/optionsdialog.ui deleted file mode 100644 index 2ea13d120e1..00000000000 --- a/Surface_mesher/demo/Surface_mesher/ui/optionsdialog.ui +++ /dev/null @@ -1,128 +0,0 @@ - - OptionDialog - - - - 0 - 0 - 210 - 167 - - - - Set options - - - :/icons/cgal_logo.xpm - - - - - - Sharp edges angle bounds - - - - - - - - &Lower bound - - - angle_lower_bound - - - - - - - 180.000000000000000 - - - - - - - &Upper bound - - - angle_upper_bound - - - - - - - 180.000000000000000 - - - - - - - - - - - - Qt::Vertical - - - - 20 - 0 - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok - - - - - - - - - - - buttonBox - accepted() - OptionDialog - accept() - - - 227 - 215 - - - 157 - 90 - - - - - buttonBox - rejected() - OptionDialog - reject() - - - 243 - 221 - - - 252 - 90 - - - - - diff --git a/Surface_mesher/demo/Surface_mesher/ui/raw_image.ui b/Surface_mesher/demo/Surface_mesher/ui/raw_image.ui deleted file mode 100644 index e270d1de917..00000000000 --- a/Surface_mesher/demo/Surface_mesher/ui/raw_image.ui +++ /dev/null @@ -1,454 +0,0 @@ - - Raw_image_dialog - - - - 0 - 0 - 585 - 342 - - - - Open raw image - - - - - - Image &value type - - - - - - Short (16 bits) - - - - - - - Float - - - - - - - Int (32 bits) - - - - - - - Double - - - - - - - Signed - - - - - - - char (8 bits) - - - - - - - - - - Image dimensions - - - - - - - - &Dimensions: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - dim_x - - - - - - - &Spacing: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - spacing_x - - - - - - - x: - - - 100000000 - - - - - - - y: - - - 100000000 - - - - - - - z: - - - 100000000 - - - - - - - vx: - - - 5 - - - 1.000000000000000 - - - - - - - vy: - - - 5 - - - 1.000000000000000 - - - - - - - vz: - - - 5 - - - 1.000000000000000 - - - - - - - &Offset: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - offset - - - - - - - bytes - - - 999999999 - - - - - - - Image size: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - 0 - - - - - - - File size: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - 0 - - - - - - - - - - - - QDialogButtonBox::Cancel|QDialogButtonBox::Open - - - - - - - int_bt - short_bt - signed_bt - float_bt - double_bt - dim_x - dim_y - dim_z - spacing_x - spacing_y - spacing_z - offset - buttonBox - - - - - float_bt - toggled(bool) - signed_bt - setDisabled(bool) - - - 47 - 112 - - - 553 - 94 - - - - - double_bt - toggled(bool) - signed_bt - setDisabled(bool) - - - 564 - 127 - - - 564 - 94 - - - - - buttonBox - accepted() - Raw_image_dialog - accept() - - - 191 - 316 - - - 183 - 313 - - - - - buttonBox - rejected() - Raw_image_dialog - reject() - - - 253 - 319 - - - 252 - 312 - - - - - dim_x - valueChanged(int) - Raw_image_dialog - update_image_size() - - - 178 - 187 - - - 99 - 141 - - - - - dim_z - valueChanged(int) - Raw_image_dialog - update_image_size() - - - 473 - 178 - - - 441 - 142 - - - - - char_bt - clicked() - Raw_image_dialog - update_image_size() - - - 71 - 52 - - - 137 - 3 - - - - - short_bt - clicked() - Raw_image_dialog - update_image_size() - - - 117 - 81 - - - 49 - 6 - - - - - float_bt - clicked() - Raw_image_dialog - update_image_size() - - - 137 - 111 - - - 67 - -5 - - - - - int_bt - clicked() - Raw_image_dialog - update_image_size() - - - 358 - 49 - - - 584 - 52 - - - - - dim_y - valueChanged(int) - Raw_image_dialog - update_image_size() - - - 332 - 186 - - - 271 - 142 - - - - - double_bt - clicked() - Raw_image_dialog - update_image_size() - - - 514 - 119 - - - 581 - 116 - - - - - - update_image_size() - - diff --git a/Surface_mesher/demo/Surface_mesher/ui/values_list.ui b/Surface_mesher/demo/Surface_mesher/ui/values_list.ui deleted file mode 100644 index 9e7e4372813..00000000000 --- a/Surface_mesher/demo/Surface_mesher/ui/values_list.ui +++ /dev/null @@ -1,118 +0,0 @@ - - Values_list - - - - 0 - 0 - 429 - 632 - - - - Form - - - - - - QFrame::StyledPanel - - - 1 - - - QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed|QAbstractItemView::NoEditTriggers|QAbstractItemView::SelectedClicked - - - true - - - QAbstractItemView::ExtendedSelection - - - 0 - - - false - - - true - - - false - - - true - - - false - - - 3 - - - - Iso-value - - - - - Color - - - - - Name - - - - - - - - - - ... - - - :/values/plus.png - - - - - - - ... - - - :/values/minus.png - - - Del - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - diff --git a/Surface_mesher/demo/Surface_mesher/values_list.cpp b/Surface_mesher/demo/Surface_mesher/values_list.cpp deleted file mode 100644 index b2e8a41e86f..00000000000 --- a/Surface_mesher/demo/Surface_mesher/values_list.cpp +++ /dev/null @@ -1,280 +0,0 @@ -#include "values_list.h" -#include "ui_values_list.h" -#include "colorlisteditor.h" -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) -#include -#endif - -Values_delegate::Values_delegate(QWidget* parent) : QItemDelegate(parent) {} -void Values_delegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const -{ - switch(index.column()) - { - case Values_list::Color: { - painter->fillRect(option.rect, index.data().value()); - drawFocus(painter, option, option.rect); - break; - } - default: - QItemDelegate::paint(painter, option, index); - } -} - -QWidget *Values_delegate::createEditor(QWidget *parent, - const QStyleOptionViewItem & option, - const QModelIndex & index) const -{ - if(index.column() == Values_list::Color) - { - return new ColorListEditor(parent); - } - else if(index.column() == Values_list::Value) - { - QLineEdit* lineedit = new QLineEdit(parent); - lineedit->setAutoFillBackground(true); - lineedit->setValidator(new QDoubleValidator(lineedit)); - return lineedit; - } - else return QItemDelegate::createEditor(parent, option, index); -} - -void Values_delegate::setEditorData(QWidget *editor, - const QModelIndex &index) const -{ - if(index.column() == Values_list::Color) - { - ColorListEditor* coloreditor = qobject_cast(editor); - if(coloreditor) - coloreditor->setColor(index.data().value()); - } - else if(index.column() == Values_list::Value) - { - QLineEdit* lineedit = qobject_cast(editor); - if(lineedit) - lineedit->setText(index.data().toString()); - } - else QItemDelegate::setEditorData(editor, index); -} -void Values_delegate::setModelData(QWidget *editor, QAbstractItemModel *model, - const QModelIndex &index) const -{ - if(index.column() == Values_list::Color) - { - ColorListEditor* coloreditor = qobject_cast(editor); - if(coloreditor) - { - model->setData(index, coloreditor->color()); - Q_EMIT new_color(index); - } - } - else if(index.column() == Values_list::Value) - { - QLineEdit* lineedit = qobject_cast(editor); - if(lineedit) - { - model->setData(index, lineedit->text().toDouble()); - Q_EMIT new_value(index); - } - } - else QItemDelegate::setModelData(editor, model, index); -} - -const double Values_list::default_value = 0.0; - -Values_list::Values_list(QWidget* parent): - QWidget(parent) -{ - Ui::Values_list().setupUi(this); - - treeWidget = parent->findChild("treeWidget"); - Q_ASSERT_X(treeWidget, "Values_list constructor", "cannot find widget \"treeWidget\""); - - treeWidget->sortByColumn(Value, Qt::AscendingOrder); - - treeWidget->header()->setSectionsClickable(false); - - - Values_delegate* values_delegate = new Values_delegate(parent); - - treeWidget->setItemDelegate(values_delegate); - connect(values_delegate, SIGNAL(new_value(const QModelIndex&)), - this, SIGNAL(values_changed())); - connect(values_delegate, SIGNAL(new_color(const QModelIndex&)), - this, SIGNAL(colors_changed())); - connect(this->treeWidget->model(), - SIGNAL(dataChanged (const QModelIndex &, const QModelIndex &)), - this, SIGNAL(changed())); - - connect(this, SIGNAL(changed()), - this, SLOT(update_items_cache())); -} - -QColor Values_list::color(const int i) const -{ - if(i < 0 || i > treeWidget->topLevelItemCount()) - return QColor(); - else - return treeWidget->topLevelItem(i)->data(Color, Qt::DisplayRole).value(); -} - -QColor Values_list::color(const QTreeWidgetItem* item) const -{ - return item->data(Color, Qt::DisplayRole).value(); -} - -int Values_list::numberOfValues() const -{ - return treeWidget->topLevelItemCount(); -} - -double Values_list::value(const int i) const -{ - if(i < 0 || i > numberOfValues()) - return 0.; - else - return treeWidget->topLevelItem(i)->data(Value, Qt::DisplayRole).toDouble(); -} - -QString Values_list::name(const int i) const -{ - if(i < 0 || i > treeWidget->topLevelItemCount()) - return QString(); - else - return treeWidget->topLevelItem(i)->data(Name, Qt::DisplayRole).toString(); -} - -bool Values_list::enabled(const int i) const -{ - if(i < 0 || i > treeWidget->topLevelItemCount()) - return false; - else - return treeWidget->topLevelItem(i)->data(Value, Qt::CheckStateRole).toInt() > 0; -} - -bool Values_list::enabled(const QTreeWidgetItem* item) const -{ - return item->data(Value, Qt::CheckStateRole).toInt() > 0; -} - -const QTreeWidgetItem* Values_list::item(const int i) const -{ - if(i < 0 || i > treeWidget->topLevelItemCount()) - return 0; - else - return treeWidget->topLevelItem(i); -} - -void Values_list::save_values(QString filename) const -{ - QSettings settings; - - settings.beginGroup(QUrl::toPercentEncoding(filename)); - settings.beginWriteArray("values"); - for (int i = 0; i < numberOfValues(); ++i) { - settings.setArrayIndex(i); - settings.setValue("value", value(i)); - settings.setValue("color", color(i)); - settings.setValue("name", name(i)); - settings.setValue("enabled", enabled(i)); - } - settings.endArray(); - settings.endGroup(); -} - -void Values_list::load_values(QString filename) -{ - QSettings settings; - - treeWidget->clear(); - settings.beginGroup(QUrl::toPercentEncoding(filename)); - int nb = settings.beginReadArray("values"); - for (int i = 0; i < nb; ++i) { - settings.setArrayIndex(i); - QTreeWidgetItem *newItem = new QTreeWidgetItem(treeWidget); - newItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable); - newItem->setData(Value, Qt::CheckStateRole, settings.value("enabled").toBool() ? Qt::Checked : Qt::Unchecked); - newItem->setData(Value, Qt::DisplayRole, settings.value("value").toDouble()); - newItem->setData(Color, Qt::DisplayRole, settings.value("color").value()); - newItem->setData(Name, Qt::DisplayRole, settings.value("name").toString()); - } - settings.endArray(); - settings.endGroup(); - update_items_cache(); -} - -void Values_list::on_minusButton_clicked() -{ - Q_FOREACH(QTreeWidgetItem* item, treeWidget->selectedItems()) - { - // treeWidget->invisibleRootItem()->removeChild(item); - delete item; - } - Q_EMIT values_changed(); -} - -void Values_list::on_plusButton_clicked() -{ - addValue(); -} - -void Values_list::addValue(const double i) -{ - QTreeWidgetItem *newItem = new QTreeWidgetItem(treeWidget); - newItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable); - newItem->setData(Value, Qt::CheckStateRole, Qt::Checked); - newItem->setData(Value, Qt::DisplayRole, i); - QStringList colors = QColor::colorNames(); -#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) - const int color_index = qrand() % colors.size(); -#else -const int color_index = QRandomGenerator::global()->generate() % colors.size(); -#endif - - QColor color = QColor(colors[color_index]); - newItem->setData(Color, Qt::DisplayRole, color); - newItem->setData(Name, Qt::DisplayRole, ""); - Q_EMIT values_changed(); -} - -void Values_list::update_items_cache() { - items_cache.clear(); - for(int i = 0, nb = numberOfValues(); i < nb; ++i) { - items_cache.insert(std::make_pair(value(i), item(i))); - } -} - -const QTreeWidgetItem* Values_list::search(const double value) const -{ - Items_cache::const_iterator it = items_cache.find(value); - if(it != items_cache.end()) { - return it->second; - } - else { - return 0; - } -} - -void Values_list::setHeaderTitle(QString title) -{ - treeWidget->headerItem()->setText(0, title); -} - diff --git a/Surface_mesher/demo/Surface_mesher/values_list.h b/Surface_mesher/demo/Surface_mesher/values_list.h deleted file mode 100644 index 03649fea0f0..00000000000 --- a/Surface_mesher/demo/Surface_mesher/values_list.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef _VALUES_LIST_H -#define _VALUES_LIST_H - -#include -#include -#include -#include -#include - -class QTreeWidget; -class QTreeWidgetItem; - -class Values_delegate : public QItemDelegate -{ - Q_OBJECT -public: - Values_delegate(QWidget* parent); - -Q_SIGNALS: - void new_color(const QModelIndex&) const; - void new_value(const QModelIndex&) const; - -protected: - void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const; - QWidget *createEditor(QWidget *parent, - const QStyleOptionViewItem & option, - const QModelIndex & index) const; - void setEditorData(QWidget *editor, - const QModelIndex &index) const; - void setModelData(QWidget *editor, QAbstractItemModel *model, - const QModelIndex &index) const; -}; - -class Values_list : public QWidget -{ - Q_OBJECT -public: - enum Field { Value = 0 , Color = 1, Name = 2}; - Values_list(QWidget* parent); - - // const accessors - int numberOfValues() const; - QColor color(const int i) const; - QColor color(const QTreeWidgetItem* i) const; - double value(const int i) const; - QString name(const int i) const; - bool enabled(const int i) const; - bool enabled(const QTreeWidgetItem* i) const; - const QTreeWidgetItem* item(const int i) const; - const QTreeWidgetItem* search(const double value) const; - -public Q_SLOTS: - void save_values(QString) const; - void load_values(QString); - void on_plusButton_clicked(); - void on_minusButton_clicked(); - - // setters - void addValue(const double v = Values_list::default_value); - - void setHeaderTitle(QString); - -private Q_SLOTS: - void update_items_cache(); - -Q_SIGNALS: - void changed(); - void colors_changed(); - void values_changed(); -private: - QTreeWidget* treeWidget; - typedef std::map Items_cache; - Items_cache items_cache; - - static const double default_value; -}; - -#endif // _VALUES_LIST_H - diff --git a/Surface_mesher/demo/Surface_mesher/values_list.qrc b/Surface_mesher/demo/Surface_mesher/values_list.qrc deleted file mode 100644 index 8a78bb1688a..00000000000 --- a/Surface_mesher/demo/Surface_mesher/values_list.qrc +++ /dev/null @@ -1,6 +0,0 @@ - - - icons/minus.png - icons/plus.png - - diff --git a/Surface_mesher/demo/Surface_mesher/viewer.cpp b/Surface_mesher/demo/Surface_mesher/viewer.cpp deleted file mode 100644 index 0cde258c258..00000000000 --- a/Surface_mesher/demo/Surface_mesher/viewer.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "viewer.h" -#include "surface.h" -#include -#include - -Viewer::Viewer(QWidget* parent) - : CGAL::QGLViewer(parent), surface(nullptr) -{ -} - -void Viewer::init() -{ - setBackgroundColor(Qt::white); - glLineStipple(5, 0xaaaa); - glDisable(GL_LINE_STIPPLE); - - // anti-aliasing - glEnable(GL_BLEND); - glEnable(GL_LINE_SMOOTH); - glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -} - -QString Viewer::helpString() const -{ - return "" - "

    Surface mesher demo

    \n" - "

    No help availlable for now.

    "; -} - -void Viewer::interpolateToFitBoundingBox(double xmin, double ymin, double zmin, - double xmax, double ymax, double zmax) -{ - QAction* auto_resize = parent()->parent()->findChild("actionAuto_resize"); - Q_ASSERT_X(auto_resize, "Viewer::interpolateToFitBoundingBox", "cannot find action \"actionAuto_resize\""); - if(auto_resize && auto_resize->isChecked()) - { - 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.); - } -} - -void Viewer::draw() -{ - if(surface) - surface->draw(); -} - -void Viewer::drawWithNames() -{ - if(surface) - surface->drawWithNames(); -} -void Viewer::postSelection(const QPoint& p) -{ - if(surface) - surface->postSelection(p); -} - -void Viewer::set_surface(Surface* s) -{ - surface = s; -} - diff --git a/Surface_mesher/demo/Surface_mesher/viewer.h b/Surface_mesher/demo/Surface_mesher/viewer.h deleted file mode 100644 index 8c40a6a6612..00000000000 --- a/Surface_mesher/demo/Surface_mesher/viewer.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _VIEWER_H -#define _VIEWER_H - -#include -#include - -class Surface; - -class Viewer : public CGAL::QGLViewer -{ - Q_OBJECT -public: - Viewer(QWidget* parent); - - void set_surface(Surface*); - -public Q_SLOTS: - void interpolateToFitBoundingBox(double, double, double, double, double, double); - -protected : - virtual void init(); - virtual void draw(); - virtual void drawWithNames(); - virtual void postSelection(const QPoint&); - virtual QString helpString() const; - - Surface* surface; -}; - -#endif // _VIEWER_H diff --git a/Surface_mesher/demo/Surface_mesher/volume.cpp b/Surface_mesher/demo/Surface_mesher/volume.cpp deleted file mode 100644 index 62424155ccd..00000000000 --- a/Surface_mesher/demo/Surface_mesher/volume.cpp +++ /dev/null @@ -1,1613 +0,0 @@ -#include - -#include "volume.h" - -#include // std::sort -#include -#include - -#include - -#include "viewer.h" -#include "mainwindow.h" -#include "values_list.h" - -#include "File_XT.h" // format XT from Total/ELF - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "Raw_image_dialog.h" -#include -// #include -#include -#include -#include -#include -#include - -struct Threshold : public CGAL::cpp98::unary_function { - double isovalue; - bool is_identity; - - Threshold(double isovalue) : isovalue(isovalue), is_identity(false) {} - - result_type operator()(FT value) - { - if(is_identity) - return static_cast(value); - else if(value >= isovalue) - return 1; - else - return 0; - } -}; - -class Classify_from_isovalue_list : - public CGAL::cpp98::unary_function -{ - typedef std::pair Isovalue; - typedef std::vector Isovalues; - boost::shared_ptr isovalues; - bool is_identity; - - struct Sort_isovalues : CGAL::cpp98::binary_function - { - bool operator()(const Isovalue& isoval1, const Isovalue& isoval2) - { - return isoval1.first < isoval2.first; - } - }; -public: - Classify_from_isovalue_list(Values_list * list) - : is_identity(false) - { - isovalues = boost::shared_ptr(new Isovalues(list->numberOfValues())); - for(int i = 0, nbs = list->numberOfValues(); i < nbs; ++i ) - (*isovalues)[i] = std::make_pair(list->value(i), i); - std::sort(isovalues->begin(), isovalues->end(), Sort_isovalues()); - } - - void set_identity(bool b) { - is_identity = b; - } - - result_type operator()(FT value) - { - if(is_identity) { - return static_cast(value); - } - result_type result = 0; -// std::cerr << "isovalues: "; - for(result_type i = 1, end = static_cast(isovalues->size()); i <= end; ++i) - { -// std::cerr << (*isovalues)[i-1] << ", "; - if(value >= (*isovalues)[i-1].first && - i >= result) - { - result = i; - } - } -// if(result>1) -// std::cerr << "result = " << (int)result << "/" << list->numberOfValues() << std::endl; -// else -// std::cerr << std::endl; - if(result>0) - return (*isovalues)[result-1].second + 1; - else - return 0; - } -}; - -class Generate_surface_identifiers : - public CGAL::cpp98::binary_function -{ - Values_list* list; - bool labellized; - -public: - Generate_surface_identifiers(Values_list* list) - : list(list), labellized(false) {}; - - void set_labellized_image(bool b) - { - labellized = b; - } - - result_type operator()(const Classify_from_isovalue_list::result_type& a, - const Classify_from_isovalue_list::result_type& b) - { - if(labellized) - return list->search((std::max)(a, b)); - else - return list->item((std::min)(a, b)); - } -}; - -// class Classify_from_isovalue_list : -// public CGAL::cpp98::unary_function -// { -// typedef std::pair Isovalue; -// typedef std::vector Isovalues; -// boost::shared_ptr isovalues; - -// struct Sort_isovalues : CGAL::cpp98::binary_function -// { -// bool operator()(const Isovalue& isoval1, const Isovalue& isoval2) -// { -// return isoval1.first < isoval2.first; -// } -// }; -// public: -// Classify_from_isovalue_list(Isovalues_list * list) -// { -// isovalues = boost::shared_ptr(new Isovalues(list->numberOfIsoValues())); -// for(int i = 0, nbs = list->numberOfIsoValues(); i < nbs; ++i ) -// (*isovalues)[i] = std::make_pair(list->isovalue(i), list->item(i)); -// std::sort(isovalues->begin(), isovalues->end(), Sort_isovalues()); -// } - -// result_type operator()(FT value) -// { -// int result = 0; -// // std::cerr << "isovalues: "; -// for(int i = 1, end = isovalues->size(); i <= end; ++i) -// { -// // std::cerr << (*isovalues)[i-1] << ", "; -// if(value >= (*isovalues)[i-1].first && -// i >= result) -// { -// result = i; -// } -// } -// if(result>1) -// std::cerr << boost::format("result = %1%/%2%\n") % result % isovalues->size(); -// if(result>0) -// return (*isovalues)[result-1].second; -// else -// return 0; -// } -// }; -Volume::Volume(MainWindow* mw) : - Surface(mw), - m_sm_angle(30), - m_sm_radius(0), - m_sm_distance(0), - m_relative_precision(0.000000001), - m_view_surface(false), - m_triangulation_color(QColor(Qt::green)), - m_inverse_normals(false), - two_sides(false), - del(), - c2t3(del), - mw(mw), - lists_draw_surface(), - lists_draw_surface_is_valid(false), -#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - list_draw_marching_cube(0), - list_draw_marching_cube_is_valid(false), - lists_draw_surface_mc(), -#endif // CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - m_view_mc(false) -{ - spinBox_radius_bound = mw->findChild("spinBox_radius_bound"); - spinBox_distance_bound = mw->findChild("spinBox_distance_bound"); - Q_ASSERT_X(spinBox_radius_bound && spinBox_distance_bound, - "Volume::Volume()", "Cannot find spinboxes!"); - - values_list = mw->values; - - connect(spinBox_radius_bound, SIGNAL(valueChanged(double)), - this, SLOT(set_radius_bound(double))); - connect(spinBox_distance_bound, SIGNAL(valueChanged(double)), - this, SLOT(set_distance_bound(double))); - - connect(mw->actionSurface_mesher, SIGNAL(triggered()), - this, SLOT(display_surface_mesher_result())); - - connect(mw->actionInverse_normals, SIGNAL(toggled(bool)), - this, SLOT(set_inverse_normals(bool))); - m_inverse_normals = mw->actionInverse_normals->isChecked(); - - connect(mw->actionDisplay_front_and_back, SIGNAL(toggled(bool)), - this, SLOT(set_two_sides(bool))); - two_sides = mw->actionDisplay_front_and_back->isChecked(); - - connect(mw->actionDraw_triangles_edges, SIGNAL(toggled(bool)), - this, SLOT(set_draw_triangles_edges(bool))); - draw_triangles_edges = mw->actionDraw_triangles_edges->isChecked(); - - connect(mw->actionUse_Gouraud_shading, SIGNAL(toggled(bool)), - this, SLOT(set_use_gouraud(bool))); - use_gouraud = mw->actionUse_Gouraud_shading->isChecked(); - - connect(mw->actionShow_the_image_bounding_box, SIGNAL(toggled(bool)), - this, SLOT(set_show_bbox(bool))); - show_bbox = mw->actionShow_the_image_bounding_box->isChecked(); - - connect(mw->actionShow_triangulation, SIGNAL(toggled(bool)), - this, SLOT(set_draw_triangulation(bool))); - m_draw_triangulation = mw->actionShow_triangulation->isChecked(); - - connect(mw->actionTriangulation_edges_color, SIGNAL(triggered()), - this, SLOT(set_triangulation_edges_color())); - - connect(this, SIGNAL(new_bounding_box(double, double, double, double, double, double)), - mw->viewer, SLOT(interpolateToFitBoundingBox(double, double, double, double, double, double))); - - connect(values_list, SIGNAL(values_changed()), - this, SLOT(changed_parameters())); - connect(values_list, SIGNAL(changed()), - mw->viewer, SLOT(updateGL())); - connect(this, SIGNAL(changed()), - this, SLOT(check_can_export_off())); - - connect(mw->labellizedRadioButton, SIGNAL(toggled(bool)), - this, SLOT(labellizedToogled(bool))); - - mw->actionExport_surface_mesh_to_OFF->setEnabled(false); - connect(mw->actionExport_surface_mesh_to_OFF, SIGNAL(triggered()), - this, SLOT(export_off())); - - connect(mw->actionSave, SIGNAL(triggered()), - this, SLOT(save_image_to_inr())); - -#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - connect(mw->actionMarching_cubes, SIGNAL(triggered()), - this, SLOT(display_marchin_cube())); -#endif -} - -void Volume::set_inverse_normals(const bool b) { - m_inverse_normals = b; - - list_draw_marching_cube = 0; // Invalidate the display list for the - // marching cube. See gl_draw_marchingcube() - // for an explanation. - - Q_EMIT changed(); -} - -void Volume::set_two_sides(const bool b) { - two_sides = b; - Q_EMIT changed(); -} - -void Volume::set_draw_triangles_edges(const bool b) { - draw_triangles_edges = b; - Q_EMIT changed(); -} - -void Volume::set_draw_triangulation(const bool b) { - m_draw_triangulation = b; - Q_EMIT changed(); -} - -void Volume::set_triangulation_edges_color() { - const QColor color = QColorDialog::getColor(m_triangulation_color, mw); - if (color.isValid()) { - m_triangulation_color = color; - Q_EMIT changed(); - } -} - -void Volume::set_use_gouraud(const bool b) { - use_gouraud = b; - Q_EMIT changed(); -} - -void Volume::set_show_bbox(const bool b) { - show_bbox = b; - Q_EMIT changed(); -} - -void Volume::only_in() -{ - mw->show_only("volume"); -#ifndef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - mw->actionMarching_cubes->setVisible(false); -#endif -} - -#ifdef CGAL_USE_VTK - -#include - -#include -#include -#include -#include -#include - -Volume::~Volume() -{ - if(vtk_reader) vtk_reader->Delete(); - if(vtk_image) vtk_image->Delete(); - if(dicom_reader) dicom_reader->Delete(); - if(executive) executive->Delete(); - if(smoother) smoother->Delete(); -} - -bool Volume::opendir(const QString& dirname) -{ - bool result = true; - if(!fileinfo.isReadable()) - { - QMessageBox::warning(mw, mw->windowTitle(), - tr("Cannot read directory %1!").arg(dirname)); - status_message(tr("Opening of directory %1 failed!").arg(dirname)); - result = false; - } - else - { - dicom_reader = vtkDICOMImageReader::New(); - dicom_reader->SetDirectoryName(dirname.toUtf8()); - - executive = - vtkDemandDrivenPipeline::SafeDownCast(dicom_reader->GetExecutive()); - if (executive) - { - executive->SetReleaseDataFlag(0, 0); // where 0 is the port index - } - - smoother = vtkImageGaussianSmooth::New(); - smoother->SetStandardDeviations(1., 1., 1.); - smoother->SetInputConnection(dicom_reader->GetOutputPort()); - smoother->Update(); - vtk_image = smoother->GetOutput(); - vtk_image->Print(std::cerr); - m_image = CGAL::read_vtk_image_data(vtk_image); - if(m_image.image() == 0) - { - QMessageBox::warning(mw, mw->windowTitle(), - tr("Error with file %1/:\nunknown file format!").arg(dirname)); - status_message(tr("Opening of file %1/ failed!").arg(dirname)); - result = false; - } - else - { - status_message(tr("File %1/ successfully opened.").arg(dirname)); - finish_open(); - result = true; - } - // if(executive) executive->Delete(); - // dicom_reader->Delete(); - // smoother->Delete(); - } - return result; -} - -bool Volume::open_vtk(const QString& filename) -{ - only_in(); - - fileinfo.setFile(filename); - - if(fileinfo.isDir()) - { - return opendir(filename); - } - - if(!fileinfo.isReadable()) - { - QMessageBox::warning(mw, mw->windowTitle(), - tr("Cannot read file %1!").arg(filename)); - status_message(tr("Opening of file %1 failed!").arg(filename)); - return false; - } - else - { - vtk_reader = vtkImageReader::New(); - vtk_reader->SetFileName(filename.toUtf8()); - vtk_reader->SetDataScalarTypeToUnsignedChar(); - vtk_reader->SetDataExtent(0, 249, 0, 249, 0, 124); - vtk_reader->SetDataSpacing(1., 1., 1.); - vtk_reader->SetFileDimensionality(3); - vtk_reader->Update(); - vtk_reader->Print(std::cerr); - vtk_image = vtk_reader->GetOutput(); - vtk_image->Print(std::cerr); - m_image = CGAL::read_vtk_image_data(vtk_image); - if(m_image.image() == NULL) - { - QMessageBox::warning(mw, mw->windowTitle(), - tr("Error with file %1:\nunknown file format!").arg(filename)); - status_message(tr("Opening of file %1 failed!").arg(filename)); - return false; - } - else - { - status_message(tr("File %1 successfully opened.").arg(filename)); - finish_open(); - return true; - } - } -} - -// Total 3D images (XT format, that is the old Inrimage format, 1994. -bool Volume::open_xt(const QString& filename) -{ - only_in(); - - fileinfo.setFile(filename); - - if(fileinfo.isDir()) - { - return false; - } - - if(!fileinfo.isReadable()) - { - QMessageBox::warning(mw, mw->windowTitle(), - tr("Cannot read file %1!").arg(filename)); - status_message(tr("Opening of file %1 failed!").arg(filename)); - return false; - } - else - { - long dimx, dimy, dimz; - long word_dim; - long header_size; - const char* filename_stl = qPrintable(filename); - CGAL::Total::lire_longueur_entete(filename_stl, &header_size); - CGAL::Total::lire_nb_octet(filename_stl, &word_dim); - CGAL::Total::lire_longueur_trace(filename_stl, &dimx); - CGAL::Total::lire_nb_trace(filename_stl, &dimy); - CGAL::Total::lire_nb_plan(filename_stl, &dimz); - - vtkImageReader* vtk_reader = vtkImageReader::New(); - vtk_reader->SetFileName(filename_stl); - switch(word_dim) { - case 8: - vtk_reader->SetDataScalarTypeToUnsignedChar(); - break; - case 16: - vtk_reader->SetDataScalarTypeToUnsignedShort(); - break; - default: - return false; - } - vtk_reader->SetHeaderSize(header_size); - vtk_reader->SetDataExtent(1, int(dimx), 1, int(dimy), 1, int(dimz)); - vtk_reader->SetDataSpacing(1., 1., 1.); - vtk_reader->SetFileDimensionality(3); - vtk_reader->Update(); - vtk_reader->Print(std::cerr); - vtkImageData* vtk_image = vtk_reader->GetOutput(); - vtk_image->Print(std::cerr); - m_image = CGAL::read_vtk_image_data(vtk_image); - if(m_image.image() != NULL) - { - QMessageBox::warning(mw, mw->windowTitle(), - tr("Error with file %1:\nunknown file format!").arg(filename)); - status_message(tr("Opening of file %1 failed!").arg(filename)); - return false; - } - else - { - status_message(tr("File %1 successfully opened.").arg(filename)); - finish_open(); - } - return true; - } -} - -#else // CGAL_USE_VTK -Volume::~Volume() -{ -} - -bool Volume::opendir(const QString&) -{ - return false; -} - -bool Volume::open_xt(const QString&) -{ - return false; -} -#endif // CGAL_USE_VTK - -bool Volume::open(const QString& filename) -{ - only_in(); - - fileinfo.setFile(filename); - - if(fileinfo.isDir()) - { - return opendir(filename); - } - - if(!fileinfo.isReadable()) - { - QMessageBox::warning(mw, mw->windowTitle(), - tr("Cannot read file %1!").arg(filename)); - } - else - { - if(m_image.read(filename.toStdString().c_str())) - { - status_message(tr("File %1 successfully opened.").arg(filename)); - finish_open(); - return true; - } - else if(open_xt(filename)) { - return true; - } - else - { - QSettings settings; - settings.beginGroup(QUrl::toPercentEncoding(fileinfo.absoluteFilePath())); - if( settings.value("is_raw").toBool() && - m_image.read_raw(filename.toStdString().c_str(), - settings.value("dim_x").toInt(), - settings.value("dim_y").toInt(), - settings.value("dim_z").toInt(), - settings.value("spacing_x").toDouble(), - settings.value("spacing_y").toDouble(), - settings.value("spacing_z").toDouble(), - settings.value("offset").toInt()) ) - { - status_message(tr("File %1 successfully opened.").arg(filename)); - finish_open(); - return true; - } - else if(QMessageBox::warning(mw, mw->windowTitle(), - tr("Error with file %1:\n" - "unknown file format!\n" - "\n" - "Open it as a raw image?").arg(filename), - QMessageBox::Yes|QMessageBox::No) == QMessageBox::Yes) - { - Raw_image_dialog raw_dialog; - raw_dialog.label_file_size->setText(QString("%1 B").arg(fileinfo.size())); - if( raw_dialog.exec() && - m_image.read_raw(filename.toStdString().c_str(), - raw_dialog.dim_x->value(), - raw_dialog.dim_y->value(), - raw_dialog.dim_z->value(), - raw_dialog.spacing_x->value(), - raw_dialog.spacing_y->value(), - raw_dialog.spacing_z->value(), - raw_dialog.offset->value()) ) - { - status_message(tr("File %1 successfully opened.").arg(filename)); - QSettings settings; - settings.beginGroup(QUrl::toPercentEncoding(fileinfo.absoluteFilePath())); - settings.setValue("is_raw", true); - settings.setValue("dim_x", raw_dialog.dim_x->value()); - settings.setValue("dim_y", raw_dialog.dim_y->value()); - settings.setValue("dim_z", raw_dialog.dim_z->value()); - settings.setValue("spacing_x", raw_dialog.spacing_x->value()); - settings.setValue("spacing_y", raw_dialog.spacing_y->value()); - settings.setValue("spacing_z", raw_dialog.spacing_z->value()); - settings.setValue("offset", raw_dialog.offset->value()); - settings.endGroup(); - finish_open(); - return true; - } - } - } - } - status_message(tr("Opening of file %1 failed!").arg(filename)); - return false; -} - -void Volume::finish_open() -{ - m_image.finish_open(); - mw->viewer->camera()->setSceneBoundingBox(CGAL::qglviewer::Vec(0, 0, 0), - CGAL::qglviewer::Vec(m_image.xmax(), - m_image.ymax(), - m_image.zmax())); - - mw->viewer->showEntireScene(); - values_list->load_values(fileinfo.absoluteFilePath()); - load_image_settings(fileinfo.absoluteFilePath()); - changed_parameters(); - Q_EMIT changed(); -} - -void Volume::export_off() -{ - QFileDialog filedialog(mw, tr("Export surface to file")); - filedialog.setFileMode(QFileDialog::AnyFile); - - filedialog.setNameFilter(tr("OFF files (*.off);;" - "All files (*)")); - - filedialog.setAcceptMode(QFileDialog::AcceptSave); - filedialog.setDefaultSuffix("off"); - if(filedialog.exec()) - { - const QString filename = filedialog.selectedFiles().front(); - std::cerr << "Saving to file \"" << filename.toLocal8Bit().data() << "\"..."; - std::ofstream out(filename.toUtf8()); - CGAL::output_surface_facets_to_off(out, c2t3); - if(!out) - { - QMessageBox::warning(mw, mw->windowTitle(), - tr("Export to the OFF file %1 failed!").arg(filename)); - status_message(tr("Export to the OFF file %1 failed!").arg(filename)); - std::cerr << " failed!\n"; - } - else - { - std::cerr << " done.\n"; - status_message(tr("Successfull export to the OFF file %1.").arg(filename)); - } - } -} - -void Volume::save_image_to_inr() -{ - QFileDialog filedialog(mw, tr("Export image to Inrimage format")); - filedialog.setFileMode(QFileDialog::AnyFile); - - filedialog.setNameFilter(tr("Inrimage files (*.inr);;" - "Compressed Inrimage files (*.inr.gz)")); - - - filedialog.setAcceptMode(QFileDialog::AcceptSave); - filedialog.setDefaultSuffix("inr.gz"); - if(filedialog.exec()) - { - const QString filename = filedialog.selectedFiles().front(); - std::cerr << "Saving image to file \"" << filename.toLocal8Bit().data() << "\"..."; - const int result = ::_writeImage(m_image.image(), filename.toUtf8()); - if(result != ImageIO_NO_ERROR) - { - QMessageBox::warning(mw, mw->windowTitle(), - tr("Export to the Inrimage file %1 failed!").arg(filename)); - status_message(tr("Export to the Inrimage file %1 failed!").arg(filename)); - std::cerr << " failed!\n"; - } - else - { - std::cerr << " done.\n"; - status_message(tr("Successfull export to the Inrimage file %1.").arg(filename)); - } - } -} - -void Volume::check_can_export_off() -{ - mw->actionExport_surface_mesh_to_OFF->setEnabled(m_view_surface);// || m_view_mc); -} - -void Volume::status_message(QString string) -{ - std::cerr << qPrintable(string) << std::endl; - mw->statusBar()->showMessage(string); -} - -void Volume::busy() const -{ - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); -} - -void Volume::not_busy() const -{ - QApplication::restoreOverrideCursor(); -} - -void Volume::display_marchin_cube() -{ -#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - if(m_surface_mc.empty()) - { - QElapsedTimer total_time; - total_time.start(); - - values_list->save_values(fileinfo.absoluteFilePath()); - - unsigned int nx = m_image.xdim(); - unsigned int ny = m_image.ydim(); - unsigned int nz = m_image.zdim(); - if(nx * ny * nz == 0) - { - status_message("No volume loaded."); - return; - } - - mc_timer.reset(); - busy(); - status_message("Marching cubes..."); - - mc_timer.start(); - m_surface_mc.clear(); - - if(mc.ntrigs()!=0) - mc.clean_all(); - mc.set_resolution(nx,ny,nz); - mc.init_all(); - mc.set_ext_data(static_cast(m_image.image()->data)); - - nbs_of_mc_triangles.resize(values_list->numberOfValues()); - - for(int value_id = 0; - value_id < values_list->numberOfValues(); - ++value_id) - { - status_message(tr("Marching cubes, isovalue #%1...").arg(value_id)); - - // set data -// for(unsigned int i=0;i 0) - mc.init_temps(); - mc.run(values_list->value(value_id), - m_image.vx(), - m_image.vy(), - m_image.vz()); - mc.clean_temps(); - - std::vector facets; - mc.get_facets(facets); - - mc_timer.stop(); - const unsigned int begin = value_id == 0 ? 0 : nbs_of_mc_triangles[value_id-1]; - const unsigned int nbt = facets.size() / 9; - for(unsigned int i=begin;iitem(value_id))); - } - nbs_of_mc_triangles[value_id]=m_surface_mc.size(); - mc_timer.start(); - } - mc_timer.stop(); - not_busy(); - mc_total_time = total_time.elapsed(); - - // invalidate the display list - lists_draw_surface_mc_is_valid = false; - list_draw_marching_cube_is_valid = false; - } - CGAL::Bbox_3 bbox(0,0,0,0,0,0); - for(std::vector::const_iterator - it = m_surface_mc.begin(), end = m_surface_mc.end(); - it != end; ++it) - { - bbox = bbox + it->get<0>().bbox(); - } - - m_view_mc = true; - m_view_surface = false; - Q_EMIT changed(); - if(!m_surface_mc.empty()) - { - Q_EMIT new_bounding_box(bbox.xmin(), - bbox.ymin(), - bbox.zmin(), - bbox.xmax(), - bbox.ymax(), - bbox.zmax()); - } - status_message(tr("Marching cubes done. %2 facets in %1s (CPU time), total time is %3s.") - .arg(mc_timer.time()) - .arg(m_surface_mc.size()) - .arg(mc_total_time/1000.)); - - save_image_settings(fileinfo.absoluteFilePath()); -#endif // CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE -} - -void Volume::display_surface_mesher_result() -{ - if(m_surface.empty() || // Either the surface is not computed. - m_view_surface) // Or it is computed and displayed, and one want - // to recompute it. - { - QElapsedTimer total_time; - total_time.start(); - - values_list->save_values(fileinfo.absoluteFilePath()); - - std::size_t nx = m_image.xdim(); - std::size_t ny = m_image.ydim(); - std::size_t nz = m_image.zdim(); - if(nx * ny * nz == 0) - { - status_message("No volume loaded."); - return; - } - - m_surface.clear(); - sm_timer.reset(); - busy(); - - status_message("Surface meshing..."); - - sm_timer.start(); - - c2t3.clear(); - del.clear(); - Sphere bounding_sphere(m_image.center(),m_image.radius()*m_image.radius()); - - Classify_from_isovalue_list classify(values_list); - Generate_surface_identifiers generate_ids(values_list); - - m_image.set_interpolation(mw->interpolationCheckBox->isChecked()); - if(mw->labellizedRadioButton->isChecked()) { - std::cerr << "Labellized image\n"; - } - m_image.set_labellized(mw->labellizedRadioButton->isChecked()); - classify.set_identity(mw->labellizedRadioButton->isChecked()); - generate_ids.set_labellized_image(mw->labellizedRadioButton->isChecked()); - - // definition of the surface - Surface_3 surface(m_image, bounding_sphere, m_relative_precision); -// Threshold threshold(m_image.isovalue()); - - // surface mesh traits class - typedef CGAL::Surface_mesher::Implicit_surface_oracle_3 Oracle; - Oracle oracle(classify, generate_ids); - - if(mw->searchSeedsCheckBox->isChecked()) - { - typedef std::vector > Seeds; - Seeds seeds; - { - std::cerr << "Search seeds...\n"; - std::set domains; - search_for_connected_components(std::back_inserter(seeds), - CGAL::inserter(domains), - classify); - std::cerr << "Found " << seeds.size() << " seed(s).\n"; - - if(mw->labellizedRadioButton->isChecked() && - values_list->numberOfValues() == 0) - { - Q_FOREACH(unsigned char label, domains) { - if(label != 0) { - values_list->addValue(label); - } - } - } - } - std::ofstream seeds_out("seeds.off"); - std::ofstream segments_out("segments.txt"); - seeds_out.precision(18); - seeds_out << "OFF\n" << seeds.size() << " 0 0\n"; - segments_out.precision(18); - for(Seeds::const_iterator it = seeds.begin(), end = seeds.end(); - it != end; ++it) - { - seeds_out << it->first << std::endl; - CGAL::Random_points_on_sphere_3 random_points_on_sphere_3(it->second); - Oracle::Intersect_3 intersect = oracle.intersect_3_object(); - for(int i = 0; i < 20; ++i) - { - const Point_3 test = it->first + (*random_points_on_sphere_3++ - CGAL::ORIGIN); - CGAL::Object o = intersect(surface, Segment_3(it->first, test)); - if (const Point_3* intersection = CGAL::object_cast(&o)) { - segments_out << "2 " << it->first << " " << *intersection << std::endl; - del.insert(*intersection); - } - else - { - std::cerr << - boost::format("Error. Segment (%1%, %2%) does not intersect the surface! values=(%3%, %4%)\n") - % it->first % test - % surface(it->first) % surface(test); - } - } - } - } - else { - oracle.construct_initial_points_object()(surface, - CGAL::inserter(c2t3.triangulation()), - 20); - } - - std::ofstream points_out("initial-points.off"); - points_out.precision(18); - points_out << "OFF\n" << c2t3.triangulation().number_of_vertices() << " 0 0\n"; - for(const Tr::Vertex& v : - CGAL::make_range(c2t3.triangulation().vertices_begin(), - c2t3.triangulation().vertices_end())) - { - points_out << v.point() << std::endl; - } - - std::cerr << boost::format("Number of initial points: %1%\n") % del.number_of_vertices(); - - // defining meshing criteria - typedef CGAL::Surface_mesher::Refine_criterion Criterion; - CGAL::Surface_mesher::Curvature_size_criterion - curvature_size_criterion (m_sm_distance); - CGAL::Surface_mesher::Uniform_size_criterion - uniform_size_criterion (m_sm_radius); - CGAL::Surface_mesher::Aspect_ratio_criterion - aspect_ratio_criterion (m_sm_angle); - CGAL::Surface_mesher::Vertices_on_the_same_psc_element_criterion - vertices_on_the_same_psc_element_criterion(surface); - - std::vector criterion_vector; - criterion_vector.push_back(&aspect_ratio_criterion); - criterion_vector.push_back(&uniform_size_criterion); - criterion_vector.push_back(&curvature_size_criterion); - if(mw->sameIndexCheckBox->isChecked()) { - criterion_vector.push_back(&vertices_on_the_same_psc_element_criterion); - std::cerr << "vertices_on_the_same_psc_element_criterion is activated.\n"; - } - - typedef CGAL::Surface_mesher::Standard_criteria Criteria; - Criteria criteria(criterion_vector); - std::cerr << "Surface_mesher... angle=" << m_sm_angle << ", radius= " << m_sm_radius - << ", distance=" << m_sm_distance << "\n"; - - typedef CGAL::Surface_mesher_generator::type Surface_mesher_manifold; - - typedef CGAL::Surface_mesher_generator::type Surface_mesher_non_manifold; - - if(mw->manifoldCheckBox->isChecked()) { - // meshing surface - std::cerr << "manifold criteria is activated.\n"; -// make_surface_mesh(c2t3, surface, oracle, criteria, -// CGAL::Manifold_tag(), 0); - Surface_mesher_manifold manifold_mesher(c2t3, surface, oracle, criteria); - manifold_mesher.refine_mesh(); - } - else { -// m_view_surface = true; - Surface_mesher_non_manifold non_manifold_mesher(c2t3, surface, oracle, criteria); -#if 0 - int nb_steps = 0; -// direct_draw = true; - non_manifold_mesher.init(); - while(!non_manifold_mesher.is_algorithm_done()) { - CGAL::Null_mesh_visitor null_visitor; - non_manifold_mesher.one_step(null_visitor); - if(++nb_steps % 1000 == 0) { - CGAL::Timer timer; - std::cerr << "(process events..."; - timer.start(); - list_draw_marching_cube_is_valid = false; - lists_draw_surface_is_valid = false; - for(Tr::Finite_cells_iterator - cit = del.finite_cells_begin(), - end = del.finite_cells_end(); - cit != end; ++cit) - { - cit->info() = classify(surface(cit->circumcenter())); - } -// Q_EMIT changed(); - qApp->processEvents(); - timer.stop(); - std::cerr << timer.time() << " secondes)\n"; - } - } -#else - non_manifold_mesher.refine_mesh(); -#endif - } - sm_timer.stop(); - not_busy(); - direct_draw = false; - - for(Tr::Finite_cells_iterator - cit = del.finite_cells_begin(), - end = del.finite_cells_end(); - cit != end; ++cit) - { - cit->info() = classify(surface(cit->circumcenter())); - } - // get output surface - 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; - - // here "left" means nothing - const Point_3 left_circumcenter = cell->circumcenter(); - const Point_3 right_circumcenter = cell->neighbor(index)->circumcenter(); - - const Triangle_3 t = - Triangle_3(cell->vertex(del.vertex_triple_index(index, 0))->point(), - cell->vertex(del.vertex_triple_index(index, 1))->point(), - cell->vertex(del.vertex_triple_index(index, 2))->point()); - const Vector u = t[1] - t[0]; - const Vector v = t[2] - t[0]; - Vector n = CGAL::cross_product(u,v); - n = n / std::sqrt(n*n); - if(mw->labellizedRadioButton->isChecked()) - { - m_surface.push_back(Facet_(t, - n, - values_list->search((std::max)(surface(left_circumcenter), - surface(right_circumcenter))))); - } - else { - m_surface.push_back(Facet_(t,n,cell->vertex(del.vertex_triple_index(index, 0))->point().element_index())); - } - } - - // invalidate the display list - lists_draw_surface_is_valid = false; - sm_total_time = total_time.elapsed(); - } - - CGAL::Bbox_3 bbox(0,0,0,0,0,0); - for(std::vector::const_iterator - it = m_surface.begin(), end = m_surface.end(); - it != end; ++it) - { - bbox = bbox + it->get<0>().bbox(); - } - - // toggle visualization - m_view_mc = false; - m_view_surface = true; - Q_EMIT changed(); - if(!m_surface.empty()) - { - Q_EMIT new_bounding_box(bbox.xmin(), - bbox.ymin(), - bbox.zmin(), - bbox.xmax(), - bbox.ymax(), - bbox.zmax()); - } - status_message(tr("Surface meshing done. %1 facets in %2s (CPU time), total time is %3s.") - .arg(m_surface.size()) - .arg(sm_timer.time()) - .arg(sm_total_time/1000.)); - save_image_settings(fileinfo.absoluteFilePath()); -} - -void Volume::gl_draw_image_bbox(const float line_width, - const unsigned char red, - const unsigned char green, - const unsigned char blue) -{ - const _image* image_ptr = m_image.image(); - if(image_ptr == NULL) - return; - - glLineWidth(line_width); - glColor3ub(red,green,blue); - glBegin(GL_LINES); - - const double xmax = (image_ptr->xdim - 1.0)*(image_ptr->vx); - const double ymax = (image_ptr->ydim - 1.0)*(image_ptr->vy); - const double zmax = (image_ptr->zdim - 1.0)*(image_ptr->vz); - - glVertex3d(0.0,0.0,0.0); - glVertex3d(0.0,ymax,0.0); - - glVertex3d(0.0,ymax,0.0); - glVertex3d(0.0,ymax,zmax); - - glVertex3d(0.0,ymax,zmax); - glVertex3d(0.0,0.0,zmax); - - glVertex3d(0.0,0.0,zmax); - glVertex3d(0.0,0.0,0.0); - - glVertex3d(xmax,0.0,0.0); - glVertex3d(xmax,ymax,0.0); - - glVertex3d(xmax,ymax,0.0); - glVertex3d(xmax,ymax,zmax); - - glVertex3d(xmax,ymax,zmax); - glVertex3d(xmax,0.0,zmax); - - glVertex3d(xmax,0.0,zmax); - glVertex3d(xmax,0.0,0.0); - - glVertex3d(0.0,0.0,0.0); - glVertex3d(xmax,0.0,0.0); - - glVertex3d(0.0,0.0,zmax); - glVertex3d(xmax,0.0,zmax); - - glVertex3d(0.0,ymax,zmax); - glVertex3d(xmax,ymax,zmax); - - glVertex3d(0.0,ymax,0.0); - glVertex3d(xmax,ymax,0.0); - - glEnd(); -} - -void Volume::draw() -{ - float ambient[] = { 0.25f, - 0.20725f, - 0.20725f, - 0.922f }; - float diffuse[] = { 1.0f, - 0.829f, - 0.829f, - 0.922f }; - - float specular[] = { 0.296648f, - 0.296648f, - 0.296648f, - 0.522f }; - - float emission[] = { 0.3f, - 0.3f, - 0.3f, - 1.0f }; - float shininess[] = { 11.264f }; - - // apply - ::glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, ambient); - ::glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); - ::glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, specular); - ::glMaterialfv( GL_FRONT_AND_BACK, GL_SHININESS, shininess); - ::glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, emission); - - ::glEnable(GL_LINE_SMOOTH); - - if(two_sides) - ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); - else - ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); // default - - // draw surface mesh - if(m_view_surface) - { - ::glEnable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - ::glColor3f(0.2f, 0.2f, 1.f); - ::glEnable(GL_POLYGON_OFFSET_FILL); - ::glPolygonOffset(3.0f,-3.0f); - gl_draw_surface(); - - if(draw_triangles_edges) - { - ::glDisable(GL_LIGHTING); - ::glLineWidth(1.); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - ::glColor3ub(0,0,0); - ::glDisable(GL_POLYGON_OFFSET_FILL); - gl_draw_surface(); - } - } - -#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - // draw MC surface mesh - if(m_view_mc) - { - ::glEnable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - ::glColor3f(0.2f, 0.2f, 1.f); - ::glEnable(GL_POLYGON_OFFSET_FILL); - ::glPolygonOffset(3.0f,-3.0f); - gl_draw_surface_mc(); - - if(draw_triangles_edges) - { - ::glDisable(GL_LIGHTING); - ::glLineWidth(1.); - ::glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - ::glColor3ub(0,0,0); - ::glDisable(GL_POLYGON_OFFSET_FILL); - gl_draw_surface_mc(); - } - } -#endif // CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - - if(show_bbox) { - ::glDisable(GL_LIGHTING); - gl_draw_image_bbox(3.0f,0,0,0); - } - - if(!m_view_mc && m_draw_triangulation) - { - // draw the triangualtion - ::glColor3d(m_triangulation_color.redF(), - m_triangulation_color.greenF(), - m_triangulation_color.blueF()); - ::glLineWidth(1.0); - ::glBegin(GL_LINES); - for(Tr::Finite_edges_iterator - eit = del.finite_edges_begin(), - end = del.finite_edges_end(); - eit != end; ++eit) - { - const Point_3 p1 = eit->first->vertex(eit->second)->point(); - const Point_3 p2 = eit->first->vertex(eit->third)->point(); - ::glVertex3d(p1.x(),p1.y(),p1.z()); - ::glVertex3d(p2.x(),p2.y(),p2.z()); - } - ::glEnd(); - } -} - -void Volume::set_radius_bound(double d) -{ - m_sm_radius = FT(d); - changed_parameters(); -} - -void Volume::set_distance_bound(double d) -{ - m_sm_distance = FT(d); - changed_parameters(); -} - -#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE -void Volume::gl_draw_surface_mc() -{ - if(use_gouraud) - { - gl_draw_marchingcube(); - return; - } - - if(lists_draw_surface_mc_is_valid) - { - for(int i = 0, nbs = values_list->numberOfValues(); i < nbs; ++i ) - { - if(values_list->enabled(i)) - { - mw->viewer->qglColor(values_list->color(i)); - ::glCallList(lists_draw_surface_mc[i]); - } - } - } - else - { - lists_draw_surface_mc.resize(values_list->numberOfValues(), 0); - for(int i = 0, nbs = values_list->numberOfValues(); i < nbs; ++i ) - { - if(!lists_draw_surface_mc[i]) - { - lists_draw_surface_mc[i] = ::glGenLists(1); - } - - std::cerr << boost::format("(Re-)Generating list #%1% for marching cube surface #%2%" - " in gl_draw_surface(), ()\n") - % lists_draw_surface_mc[i] - % i; - - mw->viewer->qglColor(values_list->color(i)); - - if(lists_draw_surface_mc[i]) // If - ::glNewList(lists_draw_surface_mc[i], // lists_draw_surface[i]==0 then something - values_list->enabled(i) // got wrong in the list generation. - ? GL_COMPILE_AND_EXECUTE - : GL_COMPILE); - - - gl_draw_surface(m_surface_mc.begin(), - m_surface_mc.end(), - values_list->item(i)); - - if(lists_draw_surface_mc[i]) // If lists_draw_surface[i]==0 then - { // something got wrong in the list - ::glEndList(); // generation. - } - } - lists_draw_surface_mc_is_valid = (::glGetError() == GL_NO_ERROR); - } -} -#endif // CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - -void Volume::gl_draw_surface() -{ -// if(mw->labellizedRadioButton->isChecked()) { -// mw->viewer->qglColor(::Qt::blue); -// gl_draw_surface(m_surface.begin(), -// m_surface.end(), -// 0); -// } -// else - if(direct_draw) { - ::glBegin(GL_TRIANGLES); - unsigned int counter = 0; - for(Tr::Finite_cells_iterator - cit = del.finite_cells_begin(), end = del.finite_cells_end(); - cit != end; ++cit) - { - for(int facet_index = 0; facet_index < 4; ++facet_index) - { - const Tr::Cell_handle& facet_cell = cit; - if(c2t3.face_status(facet_cell, facet_index) == C2t3::NOT_IN_COMPLEX) { - continue; - } - const Point_3& a = facet_cell->vertex(del.vertex_triple_index(facet_index, 0))->point(); - const Point_3& b = facet_cell->vertex(del.vertex_triple_index(facet_index, 1))->point(); - const Point_3& c = facet_cell->vertex(del.vertex_triple_index(facet_index, 2))->point(); - Vector n = CGAL::cross_product(b-a,c-a); - n = n / std::sqrt(n*n); // unit normal - if(m_inverse_normals) { - ::glNormal3d(-n.x(),-n.y(),-n.z()); - } else { - ::glNormal3d(n.x(),n.y(),n.z()); - } - ::glColor3d(values_list->color(values_list->search(facet_cell->info())).redF(), - values_list->color(values_list->search(facet_cell->info())).greenF(), - values_list->color(values_list->search(facet_cell->info())).blueF()); - ::glVertex3d(a.x(),a.y(),a.z()); - ::glVertex3d(b.x(),b.y(),b.z()); - ::glVertex3d(c.x(),c.y(),c.z()); - ++counter; - } - ::glEnd(); - } - return; - } - if(!direct_draw && lists_draw_surface_is_valid) - { - for(int i = 0, nbs = values_list->numberOfValues(); i < nbs; ++i ) - { - if(values_list->enabled(i)) - { - ::glColor3d(values_list->color(i).redF(), - values_list->color(i).greenF(), - values_list->color(i).blueF()); - ::glCallList(lists_draw_surface[i]); - } - } - } - else - { - lists_draw_surface.resize(values_list->numberOfValues(), 0); - for(int i = 0, nbs = values_list->numberOfValues(); i < nbs; ++i ) - { - if(!lists_draw_surface[i]) - { - lists_draw_surface[i] = ::glGenLists(1); - } - - std::cerr << boost::format("(Re-)Generating list #%1% for surface #%2%" - " in gl_draw_surface(), ()\n") - % lists_draw_surface[i] - % i; - - ::glColor3d(values_list->color(i).redF(), - values_list->color(i).greenF(), - values_list->color(i).blueF()); - - if(!direct_draw && lists_draw_surface[i]) // If - ::glNewList(lists_draw_surface[i], // lists_draw_surface[i]==0 - values_list->enabled(i) // then something got wrong - ? GL_COMPILE_AND_EXECUTE // in the list generation. - : GL_COMPILE); - - if(!mw->labellizedRadioButton->isChecked()) - { - gl_draw_surface(m_surface.begin(), - m_surface.end(), - values_list->item(i)); - } - else - { - const auto volume_index = static_cast(values_list->value(i)); - - ::glBegin(GL_TRIANGLES); - unsigned int counter = 0; - for(C2t3::Facet_iterator - fit = c2t3.facets_begin(), end = c2t3.facets_end(); - fit != end; ++fit) - { - Tr::Cell_handle facet_cell = fit->first; - int facet_index = fit->second; - Tr::Cell_handle opposite_cell = facet_cell->neighbor(facet_index); - int opposite_index = opposite_cell->index(facet_cell); - - if( facet_cell->info() != volume_index ) { - if( opposite_cell->info() == volume_index ) { - std::swap(facet_cell, opposite_cell); - std::swap(facet_index, opposite_index); - } - else - continue; // go to next facet - } - const Point_3& a = opposite_cell->vertex(del.vertex_triple_index(opposite_index, 0))->point(); - const Point_3& b = opposite_cell->vertex(del.vertex_triple_index(opposite_index, 1))->point(); - const Point_3& c = opposite_cell->vertex(del.vertex_triple_index(opposite_index, 2))->point(); - Vector n = CGAL::cross_product(b-a,c-a); - n = n / std::sqrt(n*n); // unit normal - if(m_inverse_normals) { - ::glNormal3d(-n.x(),-n.y(),-n.z()); - } else { - ::glNormal3d(n.x(),n.y(),n.z()); - } - ::glVertex3d(a.x(),a.y(),a.z()); - ::glVertex3d(b.x(),b.y(),b.z()); - ::glVertex3d(c.x(),c.y(),c.z()); - ++counter; - } - ::glEnd(); - std::cerr << boost::format("(c2t3) number of facets: %1%\n") - % counter; - } - - if(!direct_draw && lists_draw_surface[i]) - // If lists_draw_surface[i]==0 then - { // something got wrong in the list - ::glEndList(); // generation. - } - } - lists_draw_surface_is_valid = (::glGetError() == GL_NO_ERROR); - } -} - -template -void Volume::gl_draw_surface(Iterator begin, Iterator end, const QTreeWidgetItem* i) -{ - ::glBegin(GL_TRIANGLES); - unsigned int counter = 0; - for(Iterator it = begin; it != end; ++it) - { - const Facet_& f = *it; - - if(f.get<2>() != i) continue; - - const Vector& n = f.get<1>(); - - if(m_inverse_normals) - ::glNormal3d(-n.x(),-n.y(),-n.z()); - else - ::glNormal3d(n.x(),n.y(),n.z()); - - const Triangle_3& t = f.get<0>(); - const Point_3& a = t[0]; - const Point_3& b = t[1]; - const Point_3& c = t[2]; - - ::glVertex3d(a.x(),a.y(),a.z()); - ::glVertex3d(b.x(),b.y(),b.z()); - ::glVertex3d(c.x(),c.y(),c.z()); - ++counter; - } - ::glEnd(); - std::cerr << boost::format("number of facets: %1%\n") - % counter; -} - -void Volume::changed_parameters() -{ - m_surface.clear(); -#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - m_surface_mc.clear(); -#endif - list_draw_marching_cube_is_valid = false; - lists_draw_surface_is_valid = false; - c2t3.clear(); - del.clear(); - m_view_mc = m_view_surface = false; - Q_EMIT changed(); -} - -#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE -void Volume::gl_draw_one_marching_cube_vertex(int i) -{ - if(!m_inverse_normals) - glArrayElement(i); - else - { - const Vertex* const vertex = mc.vert(i); - ::glNormal3d(-vertex->nx, -vertex->ny, -vertex->nz); - ::glVertex3d(vertex->x, vertex->y, vertex->z); - } -} - -void Volume::gl_draw_marchingcube() -{ - if(list_draw_marching_cube_is_valid) - ::glCallList(list_draw_marching_cube); - else - { - if(!list_draw_marching_cube) - list_draw_marching_cube = ::glGenLists(1); - std::cerr << boost::format("(Re-)Generating list #%1% for" - " gl_draw_marchingcube()\n") - % list_draw_marching_cube; - - if(list_draw_marching_cube) // If list_draw_marching_cube==0 then - ::glNewList(list_draw_marching_cube, // something got wrong in the list - GL_COMPILE_AND_EXECUTE); // generation. - - ::glVertexPointer(3, GL_DOUBLE, sizeof(Vertex), mc.vertices()); - ::glNormalPointer(GL_DOUBLE, sizeof(Vertex), &(mc.vertices()->nx)); - ::glEnableClientState(GL_VERTEX_ARRAY); - - // because of that conditionnal, the display list has to be - // reconstructed each time m_inverse_normals is toggled. - if(!m_inverse_normals) - ::glEnableClientState(GL_NORMAL_ARRAY); - - for(int i = 0, nbs = values_list->numberOfValues(); i < nbs; ++i) - { - const int begin = i == 0 ? 0 : nbs_of_mc_triangles[i-1]; - const int end = nbs_of_mc_triangles[i]; - mw->viewer->qglColor(values_list->color(i)); - ::glBegin(GL_TRIANGLES); - for(int i = begin; i < end; ++i) - { - const MC_Triangle* const trig = mc.trig(i); - gl_draw_one_marching_cube_vertex(trig->v1); - gl_draw_one_marching_cube_vertex(trig->v2); - gl_draw_one_marching_cube_vertex(trig->v3); - } - ::glEnd(); - } - if(list_draw_marching_cube > 0) // If list_draw_marching_cube==0 then - { // something got wrong in the list - ::glEndList(); // generation. - list_draw_marching_cube_is_valid = (::glGetError() == GL_NO_ERROR); - } - if(!list_draw_marching_cube_is_valid) - { - CGAL::Qt::opengl_check_errors(); - } - } -} -#endif // CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - -void Volume::save_image_settings(QString filename) -{ - QSettings settings; - settings.beginGroup(QUrl::toPercentEncoding(filename)); - settings.setValue("labellized", mw->labellizedRadioButton->isChecked()); - settings.endGroup(); -} - -void Volume::load_image_settings(QString filename) -{ - QSettings settings; - settings.beginGroup(QUrl::toPercentEncoding(filename)); - mw->labellizedRadioButton->setChecked(settings.value("labellized").toBool()); - settings.endGroup(); -} - -void Volume::labellizedToogled(bool toggled) -{ - if(toggled) { - values_list->setHeaderTitle(tr("Label")); - } - else { - values_list->setHeaderTitle(tr("Iso-Value")); - } -} - diff --git a/Surface_mesher/demo/Surface_mesher/volume.h b/Surface_mesher/demo/Surface_mesher/volume.h deleted file mode 100644 index 09195f02d07..00000000000 --- a/Surface_mesher/demo/Surface_mesher/volume.h +++ /dev/null @@ -1,392 +0,0 @@ -#ifndef _VOLUME_H -#define _VOLUME_H - -#include -#include -#include - - -#include "surface.h" -#include "binary_image.h" - -#include -#include -#include -#include - -#include -#include -#include // std::back_inserter - -#include -#include - -#ifdef CGAL_USE_VTK -class vtkImageReader; -class vtkImageData; -class vtkDICOMImageReader; -class vtkDemandDrivenPipeline; -class vtkImageGaussianSmooth; -#endif // CGAL_USE_VTK - -class QTreeWidgetItem; - -// kernel -// #include -#include -typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel1; - -#include -struct Kernel : public Kernel1 { - typedef CGAL::Point_with_psc_localisation Point_3; -}; - -typedef Kernel::FT FT; -typedef Kernel::Point_3 Point_3; -typedef Kernel::Sphere_3 Sphere; -typedef Kernel::Vector_3 Vector; -typedef Kernel::Triangle_3 Triangle_3; -typedef Kernel::Segment_3 Segment_3; - -// typedef CGAL::Triple Facet; - -typedef boost::tuple Facet_; - - -typedef CBinary_image_3 Binary_image; - -class QTreeWidgetItem; - -// surface mesher -// #define CGAL_MESHES_NO_OUTPUT -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef CGAL::Surface_mesh_vertex_base_3 Vb; -typedef CGAL::Triangulation_cell_base_with_info_3 Cb1; -typedef CGAL::Delaunay_triangulation_cell_base_3 Cb2; -typedef CGAL::Delaunay_triangulation_cell_base_with_circumcenter_3 Cb3; -typedef CGAL::Surface_mesh_cell_base_3 Cb; -typedef CGAL::Triangulation_data_structure_3 Tds; -typedef CGAL::Delaunay_triangulation_3 Tr; -typedef CGAL::Surface_mesh_complex_2_in_triangulation_3 C2t3; -typedef CGAL::Implicit_surface_3 Surface_3; - -#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE -#include -#endif - -class MainWindow; -class QDoubleSpinBox; -class Viewer; -class Values_list; - -class Volume : public Surface -{ - Q_OBJECT -public: - Volume(MainWindow* mw); - ~Volume(); - -private: - Binary_image m_image; - - // options - FT m_sm_angle; - FT m_sm_radius; - FT m_sm_distance; - double m_relative_precision; - - // visualization - bool m_view_surface; - bool m_draw_triangulation; - QColor m_triangulation_color; - bool m_inverse_normals; - bool two_sides; - bool draw_triangles_edges; - bool use_gouraud; - bool show_bbox; - - std::vector m_surface; - Tr del; // 3D-Delaunay triangulation - C2t3 c2t3; // 2D complex in 3D triangulation - - MainWindow* mw; - QFileInfo fileinfo; - Values_list* values_list; - QDoubleSpinBox* spinBox_radius_bound; - QDoubleSpinBox* spinBox_distance_bound; - - bool direct_draw; // do not use display lists - std::vector lists_draw_surface; - bool lists_draw_surface_is_valid; - GLint list_draw_marching_cube; - bool list_draw_marching_cube_is_valid; - - CGAL::Timer sm_timer; - int sm_total_time; - -#ifdef CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - std::vector m_surface_mc; - MarchingCubes mc ; - std::vector nbs_of_mc_triangles; - std::vector lists_draw_surface_mc; - bool lists_draw_surface_mc_is_valid; - CGAL::Timer mc_timer; - int mc_total_time; -public: - void gl_draw_surface_mc(); - void gl_draw_marchingcube(); -private: - void gl_draw_one_marching_cube_vertex(int); - -#endif // CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - - bool m_view_mc; // that boolean is here even with if - // CGAL_SURFACE_MESH_DEMO_USE_MARCHING_CUBE - // is not defined. - -#ifdef CGAL_USE_VTK - vtkImageReader* vtk_reader; - vtkImageData* vtk_image; - vtkDICOMImageReader* dicom_reader; - vtkDemandDrivenPipeline* executive; - vtkImageGaussianSmooth* smoother; -#endif // CGAL_USE_VTK - -public Q_SLOTS: -void display_marchin_cube(); - -private: - template - void gl_draw_surface(Iterator begin, Iterator end, const QTreeWidgetItem* = 0); - void gl_draw_image_bbox(const float line_width, - const unsigned char red, - const unsigned char green, - const unsigned char blue); - - template - void search_for_connected_components(PointsOutputIterator, - DomainsOutputIterator, - TransformOperator); - -public: - void gl_draw_surface(); - -Q_SIGNALS: - - void new_bounding_box(double, double, double, double, double, double); - -public Q_SLOTS: - void only_in(); - void set_inverse_normals(const bool); - void set_two_sides(const bool); - void set_draw_triangles_edges(const bool); - void set_triangulation_edges_color(); - void set_draw_triangulation(const bool); - void set_use_gouraud(const bool); - void set_show_bbox(const bool); - bool open(const QString& filename); -#ifdef CGAL_USE_VTK - bool open_vtk(const QString& filename); -#endif - bool open_xt(const QString& filename); - bool opendir(const QString& dirname); - void finish_open(); - void export_off(); - void save_image_to_inr(); - void check_can_export_off(); - void draw(); - void get_bbox(float& /*xmin*/, float& /*ymin*/, float& /*zmin*/, - float& /*xmax*/, float& /*ymax*/, float& /*zmax*/) {} - void close() {} - void display_surface_mesher_result(); - void set_radius_bound(double); - void set_distance_bound(double); - void changed_parameters(); - - void labellizedToogled(bool); - - void save_image_settings(QString); - void load_image_settings(QString); -private: - void status_message(QString); - void busy() const; - void not_busy() const; -}; - -template -void Volume::search_for_connected_components(PointsOutputIterator it, - DomainsOutputIterator dom_it, - TransformOperator transform) -{ - const std::size_t nx = m_image.xdim(); - const std::size_t ny = m_image.ydim(); - const std::size_t nz = m_image.zdim(); - - const double max_v = (std::max)((std::max)(m_image.vx(), - m_image.vy()), - m_image.vz()); - - typedef unsigned char Marker; - typedef typename TransformOperator::result_type Label; - - boost::multi_array visited(boost::extents[nx][ny][nz]); - typedef boost::tuple - Indices; - typedef std::queue Indices_queue; - typedef std::vector Border_vector; - - int number_of_connected_components = 0; - for(std::size_t i=0; i0) - continue; - const Label current_label = transform(m_image.value(i, j, k)); - *dom_it++ = current_label; - if(current_label == Label()) { - visited[i][j][k] = 3; - continue; - } - - // if we reach here, (i, j, k) is a new connected component - ++number_of_connected_components; - std::cerr << boost::format("Found new connected component (#%5%) " - "at voxel (%1%, %2%, %3%), value=%4%, volume id=%6%\n") - % i % j % k - % m_image.value(i, j, k) - % number_of_connected_components - % (int)current_label; - - int nb_voxels = 0; - - Indices_queue queue; - Indices indices(i, j ,k, 0); - queue.push(indices); - - Border_vector border; - - /* - * First pass is a BFS to retrieve all the connected component, and - * its border. - * Second pass is a BFS initialized with all voxel of the border. - * The last voxel of that BFS is used as the seed. - */ - Marker pass = 1; // pass will be equal to 2 in second pass - - Indices bbox_min = indices; - Indices bbox_max = indices; - - while(!queue.empty()) // walk through the connected component - { - Indices indices = queue.front(); - queue.pop(); - - // warning: those indices i, j and k are local to the while loop - const std::size_t i = boost::get<0>(indices); - const std::size_t j = boost::get<1>(indices); - const std::size_t k = boost::get<2>(indices); - const std::size_t depth = boost::get<3>(indices); - - if(visited[i][j][k] < pass) - { - visited[i][j][k] = pass; - if(pass == 1 ) - { - ++nb_voxels; - boost::get<0>(bbox_min) = (std::min)(i, boost::get<0>(bbox_min)); - boost::get<0>(bbox_max) = (std::max)(i, boost::get<0>(bbox_max)); - boost::get<1>(bbox_min) = (std::min)(j, boost::get<1>(bbox_min)); - boost::get<1>(bbox_max) = (std::max)(j, boost::get<1>(bbox_max)); - boost::get<2>(bbox_min) = (std::min)(k, boost::get<2>(bbox_min)); - boost::get<2>(bbox_max) = (std::max)(k, boost::get<2>(bbox_max)); - } - - static const int neighbors_offset[6][3] = { { +1, 0, 0 }, - { -1, 0, 0 }, - { 0, +1, 0 }, - { 0, -1, 0 }, - { 0, 0, +1 }, - { 0, 0, -1 } }; - bool voxel_is_on_border = false; - - // Visit neighbors. - // (i_n, j_n, k_n) are indices of neighbors. - for(int n = 0; n < 6; ++n) - { - const ptrdiff_t i_n = i + neighbors_offset[n][0]; - const ptrdiff_t j_n = j + neighbors_offset[n][1]; - const ptrdiff_t k_n = k + neighbors_offset[n][2]; - if(i_n < 0 || i_n >= static_cast(nx) || - j_n < 0 || j_n >= static_cast(ny) || - k_n < 0 || k_n >= static_cast(nz)) - { - voxel_is_on_border = true; - continue; - } - else - { - if(transform(m_image.value(i_n, j_n, k_n)) == current_label) - { - if(visited[i_n][j_n][k_n] < pass) { - Indices indices(i_n, j_n, k_n, depth+1); - queue.push(indices); - } - } - else - voxel_is_on_border = true; - } - } // end for neighbors - - if(pass == 1 && voxel_is_on_border) - border.push_back(indices); - } // end if voxel not already visited - - if(queue.empty()) { - if(pass == 1) - { // End of first pass. Begin second pass with the voxels of - // the border. - for(typename Border_vector::const_iterator - border_it = border.begin(), border_end = border.end(); - border_it != border_end; ++border_it) - queue.push(*border_it); - pass = 2; - } - else // end of second pass, return the last visited voxel - { -// if(nb_voxels >= 100) - { - *it++ = std::make_pair(m_image.point(i, j, k), (depth+1)*max_v); - std::cerr << boost::format("Found seed %5%, which is voxel (%1%, %2%, %3%), value=%4%\n") - % i % j % k % m_image.value(i, j, k) % m_image.point(i, j, k); - } - } - } // end if queue.empty() - } // end while !queue.empty() (with local indices i, j, k) - - std::cerr << boost::format("There was %1% voxel(s) in that component.\n" - "The bounding box is (%2% %3% %4%, %5% %6% %7%).\n" - "%8% voxel(s) on border\n") - % nb_voxels - % boost::get<0>(bbox_min) % boost::get<1>(bbox_min) % boost::get<2>(bbox_min) - % boost::get<0>(bbox_max) % boost::get<1>(bbox_max) % boost::get<2>(bbox_max) - % border.size(); - } // end for i,j,k -} // end function Volume::search_for_connected_components() - -#endif // _VOLUME_H diff --git a/Surface_mesher/doc/Surface_mesher/PackageDescription.txt b/Surface_mesher/doc/Surface_mesher/PackageDescription.txt index 90efa88c31c..bf46b3a6eba 100644 --- a/Surface_mesher/doc/Surface_mesher/PackageDescription.txt +++ b/Surface_mesher/doc/Surface_mesher/PackageDescription.txt @@ -38,7 +38,6 @@ \cgalPkgDependsOn{\ref PkgTriangulation3} \cgalPkgBib{cgal:ry-smg} \cgalPkgLicense{\ref licensesGPL} -\cgalPkgDemo{Surface Mesh Generator,surface_mesher.zip} \cgalPkgShortInfoEnd \cgalPkgDescriptionEnd diff --git a/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base b/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base index 59f380da802..52f282475ee 100755 --- a/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base +++ b/Surface_sweep_2/test/Surface_sweep_2/cgal_test_base @@ -28,21 +28,33 @@ fi configure() { - echo "Configuring... " + echo "Configuring... " - rm CMakeCache.txt + rm CMakeCache.txt + if [ -f "$INIT_FILE" ] + then + if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ + -DCGAL_DIR="$CGAL_DIR" \ + -DCGAL_CXX_FLAGS:STRING="$CGAL_CXX_FLAGS $TESTSUITE_CXXFLAGS" \ + -DCGAL_EXE_LINKER_FLAGS="$CGAL_EXE_LINKER_FLAGS $TESTSUITE_LDFLAGS" \ + .' ; then + echo " successful configuration" >> $ERRORFILE + else + echo " ERROR: configuration" >> $ERRORFILE + fi + else + if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ + -DCGAL_DIR="$CGAL_DIR" \ + -DCGAL_CXX_FLAGS:STRING="$TESTSUITE_CXXFLAGS" \ + -DCGAL_EXE_LINKER_FLAGS="$TESTSUITE_LDFLAGS" \ + -DCMAKE_BUILD_TYPE=NOTFOUND \ + .' ; then - if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \ - -DCGAL_DIR="$CGAL_DIR" \ - -DCGAL_CXX_FLAGS:STRING="$TESTSUITE_CXXFLAGS" \ - -DCGAL_EXE_LINKER_FLAGS="$TESTSUITE_LDFLAGS" \ - -DCMAKE_BUILD_TYPE=NOTFOUND \ - .' ; then - - echo " successful configuration" >> $ERRORFILE - else - echo " ERROR: configuration" >> $ERRORFILE - fi + echo " successful configuration" >> $ERRORFILE + else + echo " ERROR: configuration" >> $ERRORFILE + fi + fi } compile() diff --git a/TDS_2/doc/TDS_2/CGAL/Triangulation_data_structure_2.h b/TDS_2/doc/TDS_2/CGAL/Triangulation_data_structure_2.h index a5af1b6c1f0..4b2569c1607 100644 --- a/TDS_2/doc/TDS_2/CGAL/Triangulation_data_structure_2.h +++ b/TDS_2/doc/TDS_2/CGAL/Triangulation_data_structure_2.h @@ -40,8 +40,6 @@ guarantee the combinatorial validity of the resulting data structure. template< typename VertexBase, typename FaceBase > class Triangulation_data_structure_2 { public: - - /// \name Types /// @{ @@ -60,10 +58,9 @@ public: /// @} -/// \name +/// \name Ranges /// \cgalAdvancedBegin -/// In addition to the interface documented in the concept, -/// the class offers the following types. +/// In addition to the interface documented in the concept, the class offers the following types. /// \cgalAdvancedEnd /// @{ @@ -87,24 +84,24 @@ typedef Compact_container Face_range; /// @{ /*! -Returns a reference to the container of faces. +returns a reference to the container of faces. */ -Face_range & faces() const; +Face_range& faces() const; /*! -Returns a reference to the container of faces. +returns a reference to the container of faces. */ -Face_range & faces(); +Face_range& faces(); /*! -Returns a reference to the container of vertices. +returns a reference to the container of vertices. */ -Vertex_range & vertices() const; +Vertex_range& vertices() const; /*! -Returns a reference to the container of vertices. +returns a reference to the container of vertices. */ -Vertex_range & vertices(); +Vertex_range& vertices(); /// @} @@ -112,67 +109,58 @@ Vertex_range & vertices(); /// @{ /*! -Joins -the vertices that are endpoints of the edge `(f,i)`, and returns -a vertex handle to common vertex (see -Fig.\ \ref figtdssplitjoin). +joins the vertices that are endpoints of the edge `(f,i)`, and returns a vertex handle to common vertex +(see Fig.\ \ref figtdssplitjoin). + \pre `f` must be different from `Face_handle()` and `i` must be `0`, `1` or `2`. */ Vertex_handle join_vertices(Face_handle f, int i); /*! -Joins -the vertices that are endpoints of the edge `e`, and returns -a vertex handle to common vertex. +joins the vertices that are endpoints of the edge `e`, and returns a vertex handle to common vertex. */ Vertex_handle join_vertices(Edge e); /*! -Joins -the vertices that are endpoints of the edge `*eit`, and returns -a vertex handle to common vertex. +joins the vertices that are endpoints of the edge `*eit`, and returns a vertex handle to common vertex. */ Vertex_handle join_vertices(Edge_iterator eit); /*! -Joins -the vertices that are endpoints of the edge `*ec`, and returns -a vertex handle to common vertex. +joins the vertices that are endpoints of the edge `*ec`, and returns a vertex handle to common vertex. */ Vertex_handle join_vertices(Edges_circulator ec); /*! -Splits the vertex `v` into two vertices `v1` and -`v2`. The common faces `f` and `g` of `v1` and -`v2` are created after (in the counter-clockwise sense) the -faces `f1` and `f2`. The 4-tuple `(v1,v2,f,g)` is -returned (see Fig. \ref figtdssplitjoin). +splits the vertex `v` into two vertices `v1` and `v2`. + +The common faces `f` and `g` of `v1` and `v2` are created after (in the counter-clockwise sense) the +faces `f1` and `f2`. The 4-tuple `(v1,v2,f,g)` is returned (see Fig. \ref figtdssplitjoin). + \pre `dimension()` must be equal to `2`, `f1` and `f2` must be different from `Face_handle()` and `v` must be a vertex of both `f1` and `f2`. */ -boost::tuples::tuple -split_vertex(Vertex_handle v, Face_handle f1, Face_handle -f2); +boost::tuples::tuple +split_vertex(Vertex_handle v, Face_handle f1, Face_handle f2); /*! -Inserts -a degree two vertex and two faces adjacent to it that have two common -edges. The edge defined by the face handle `f` and the integer -`i` is duplicated. It returns a handle to the vertex created -(see Fig. \ref figtdsirdeg2). +inserts a degree two vertex and two faces adjacent to it that have two common edges. + +The edge defined by the face handle `f` and the integer `i` is duplicated. It returns a handle +to the vertex created (see Fig. \ref figtdsirdeg2). */ -Vertex_handle insert_degree_2(Face_handle f, int i); +Vertex_handle insert_degree_2(Face_handle f, int i); // @fixme Missing from SDG concept. Remove from here? Picture in Apollonius and SDG? /*! -Removes a degree 2 -vertex and the two faces adjacent to it. The two edges of the star of -`v` that are not incident to it are collapsed -(see Fig. \ref figtdsirdeg2). +removes a degree 2 vertex and the two faces adjacent to it. + +The two edges of the star of `v` that are not incident to it are collapsed (see Fig. \ref figtdsirdeg2). + \pre The degree of `v` must be equal to 2. */ -void remove_degree_2(Vertex_handle v); +void remove_degree_2(Vertex_handle v); // @fixme Missing from SDG concept. Remove from here? Picture in Apollonius and SDG? /// @} }; /* end Triangulation_data_structure_2 */ + } /* end namespace CGAL */ diff --git a/TDS_2/doc/TDS_2/Concepts/TriangulationDataStructure_2.h b/TDS_2/doc/TDS_2/Concepts/TriangulationDataStructure_2.h index 613eea9a70d..90a4a4cf2d8 100644 --- a/TDS_2/doc/TDS_2/Concepts/TriangulationDataStructure_2.h +++ b/TDS_2/doc/TDS_2/Concepts/TriangulationDataStructure_2.h @@ -229,7 +229,7 @@ otherwise `Vertex_handle()` is returned. \pre The optional argument `v` is a vertex of `tds_src` or is `Vertex_handle()`. */ template -Vertex_handle tds.copy_tds(const TDS_src& tds_src, typename TDS_src::Vertex_handle v, const ConvertVertex& convert_vertex, const ConvertFace& convert_face); +Vertex_handle copy_tds(const TDS_src& tds_src, typename TDS_src::Vertex_handle v, const ConvertVertex& convert_vertex, const ConvertFace& convert_face); /*! Swaps the triangulation data structure and `tds1`. diff --git a/TDS_2/doc/TDS_2/TDS_2.txt b/TDS_2/doc/TDS_2/TDS_2.txt index 79080f93963..2444eb1fb60 100644 --- a/TDS_2/doc/TDS_2/TDS_2.txt +++ b/TDS_2/doc/TDS_2/TDS_2.txt @@ -74,7 +74,7 @@ equivalent to a two-dimensional triangulated sphere. This rules extends to lower dimensional triangulation data structure arising in degenerate cases or when the triangulations -have less than three vertices. +have fewer than three vertices. A one dimensional triangulation structure maintains a set of vertices and edges which forms a ring topologically equivalent to a \f$ 1\f$-sphere. diff --git a/TDS_3/include/CGAL/Triangulation_data_structure_3.h b/TDS_3/include/CGAL/Triangulation_data_structure_3.h index 7c01149ab44..29d4372c58d 100644 --- a/TDS_3/include/CGAL/Triangulation_data_structure_3.h +++ b/TDS_3/include/CGAL/Triangulation_data_structure_3.h @@ -3669,7 +3669,7 @@ is_valid(bool verbose, int level ) const { if ( number_of_vertices() < 2 ) { if (verbose) - std::cerr << "less than 2 vertices but dimension 0" << std::endl; + std::cerr << "fewer than 2 vertices but dimension 0" << std::endl; CGAL_triangulation_assertion(false); return false; } diff --git a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/FMLS.h b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/FMLS.h index abc0b02c4be..500279aad4b 100644 --- a/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/FMLS.h +++ b/Tetrahedral_remeshing/include/CGAL/Tetrahedral_remeshing/internal/FMLS.h @@ -382,11 +382,17 @@ private: minMax[3 + j] = PN[6 * i + j]; } for (std::size_t i = 0; i < 3; i++) { - minMax[i] -= 0.001f; - minMax[3 + i] += 0.001f; + minMax[i] *= 0.99; + minMax[3 + i] *= 1.01; } + for (std::size_t i = 0; i < 3; i++) + { res[i] = (std::size_t)ceil((minMax[3 + i] - minMax[i]) / cellSize); + if(res[1] == 0) + res[i] = 1; + } + std::size_t LUTSize = res[0] * res[1] * res[2]; LUT.resize(LUTSize); LUT.assign(LUTSize, 0); @@ -463,7 +469,7 @@ private: { if (vp[j] < 0) p[j] = 0; - if (vp[j] >= res[j]) + else if (vp[j] >= res[j]) p[j] = res[j] - 1; else p[j] = static_cast(std::floor(vp[j])); diff --git a/Three/include/CGAL/Three/Scene_draw_interface.h b/Three/include/CGAL/Three/Scene_draw_interface.h index 09237363ad1..daac76b2d6f 100644 --- a/Three/include/CGAL/Three/Scene_draw_interface.h +++ b/Three/include/CGAL/Three/Scene_draw_interface.h @@ -63,13 +63,13 @@ public: * \return true if the TextItem is visible. */ virtual bool testDisplayId(double x, double y, double z, CGAL::Three::Viewer_interface* viewer) = 0; - ///\brief displays all the vertices ids if there are less than max_textItems. + ///\brief displays all the vertices ids if there are fewer than max_textItems. virtual void printVertexIds() = 0; - ///\brief displays all the edges ids if there are less than max_textItems. + ///\brief displays all the edges ids if there are fewer than max_textItems. virtual void printEdgeIds() = 0; - ///\brief displays all the faces ids if there are less than max_textItems. + ///\brief displays all the faces ids if there are fewer than max_textItems. virtual void printFaceIds() = 0; - ///\brief displays all the primitive ids if there are less than max_textItems. + ///\brief displays all the primitive ids if there are fewer than max_textItems. virtual void printAllIds() = 0; //!\brief moves the camera orthogonally to the picked face. diff --git a/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h b/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h index 7e552c06494..54d9f9d9a73 100644 --- a/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h +++ b/Triangulation/doc/Triangulation/CGAL/Regular_triangulation.h @@ -123,6 +123,53 @@ type `Weighted_point`. template< typename ForwardIterator > std::ptrdiff_t insert(ForwardIterator s, ForwardIterator e); +/*! +inserts the weighted point `p` in the triangulation on the +condition that the vertex `star_center` appears +in the conflict zone of `p` (that is, `p` would appear +in the star of `star_center` after the insertion). + +If the insertion of `p` creates a new vertex, this vertex is returned. +Otherwise, a default constructed handle is returned. + +If the dimension of the triangulation is `0` and if `p` coincides +with an existing vertex and has a greater weight, +then `p` replaces it as vertex of the triangulation +and this vertex is returned. + +If `p` coincides with an already existing vertex, with both point and +weights being equal, then this vertex is returned and the triangulation +remains unchanged. + +By convention, if the insertion of `p` would increase the dimension +of the triangulation, it is inserted. + +Prior to the actual insertion, `p` is located in the triangulation; +`start` is used as a starting place for locating `p`. + +\sa `Regular_triangulation::compute_conflict_zone()` +*/ +Vertex_handle insert_if_in_star(const Weighted_point& p, Vertex_handle star_center, + Full_cell_handle start = Full_cell_handle()); + +/*! +Same as the above `insert_if_in_star()`, but uses a vertex as starting place for the search. +*/ +Vertex_handle insert_if_in_star(const Weighted_point& p, Vertex_handle star_center, + Vertex_handle hint); + +/*! +inserts the weighted point `p` in the triangulation. + +This function is similar to the above `insert_if_in_star()` function, +but takes as additional parameters the return values of the location query +of `p`. + +\sa `Triangulation::locate()`. +*/ +Vertex_handle insert_if_in_star(const Weighted_point& p, Vertex_handle star_center, Locate_type lt, + const Face& f, const Facet& ft, Full_cell_handle s); + /// @} /// \name Queries diff --git a/Triangulation/include/CGAL/Regular_triangulation.h b/Triangulation/include/CGAL/Regular_triangulation.h index fddb395c036..86075657b06 100644 --- a/Triangulation/include/CGAL/Regular_triangulation.h +++ b/Triangulation/include/CGAL/Regular_triangulation.h @@ -974,7 +974,8 @@ Regular_triangulation // => we don't insert it if (!in_conflict) { - m_hidden_points.push_back(p); + if(only_if_this_vertex_is_in_the_cz == Vertex_handle()) + m_hidden_points.push_back(p); return Vertex_handle(); } else diff --git a/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt b/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt index 009f3845620..37544f3f199 100644 --- a/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt +++ b/Triangulation_2/doc/Triangulation_2/Triangulation_2.txt @@ -165,7 +165,7 @@ Infinite vertex and infinite faces This extends to lower dimensional triangulations arising in degenerate cases or when the triangulations -as less than three vertices. +has fewer than three vertices. Including the infinite faces, a one dimensional triangulation is a ring of edges and vertices diff --git a/Triangulation_2/include/CGAL/Regular_triangulation_2.h b/Triangulation_2/include/CGAL/Regular_triangulation_2.h index f9bf3b1ceb8..49a20bd585d 100644 --- a/Triangulation_2/include/CGAL/Regular_triangulation_2.h +++ b/Triangulation_2/include/CGAL/Regular_triangulation_2.h @@ -22,7 +22,6 @@ #include #include -#include #include #include #include diff --git a/Triangulation_2/include/CGAL/Triangulation_2/internal/Polyline_constraint_hierarchy_2.h b/Triangulation_2/include/CGAL/Triangulation_2/internal/Polyline_constraint_hierarchy_2.h index be275140aec..4b739c74f2c 100644 --- a/Triangulation_2/include/CGAL/Triangulation_2/internal/Polyline_constraint_hierarchy_2.h +++ b/Triangulation_2/include/CGAL/Triangulation_2/internal/Polyline_constraint_hierarchy_2.h @@ -46,14 +46,13 @@ private: class Node { public: explicit Node(Vertex_handle vh, bool input = false) - : vertex_(vh), id(-1), input(input) + : vertex_(vh), input(input) {} const Point& point() const { return vertex_->point(); } Vertex_handle vertex() const { return vertex_; } private: Vertex_handle vertex_; public: - int id; bool input; }; @@ -585,45 +584,58 @@ void Polyline_constraint_hierarchy_2::simplify(Vertex_it uc, Vertex_it wc) { + // TODO: How do we (want to) deal with u == w ??? Vertex_handle u = *uc, v = *vc, w = *wc; typename Sc_to_c_map::iterator uv_sc_iter = sc_to_c_map.find(make_edge(u, v)); - CGAL_assertion_msg( uv_sc_iter != sc_to_c_map.end(), "not a subconstraint" ); + typename Sc_to_c_map::iterator vw_sc_iter = sc_to_c_map.find(make_edge(v, w)); Context_list* uv_hcl = uv_sc_iter->second; - CGAL_assertion_msg((u == w) || (uv_hcl->size() == 1), "more than one constraint passing through the subconstraint" ); - - if(*(uv_hcl->front().current()) != u) { - std::swap(u,w); - uv_sc_iter = sc_to_c_map.find(make_edge(u, v)); - CGAL_assertion_msg( uv_sc_iter != sc_to_c_map.end(), "not a subconstraint" ); - uv_hcl = (*uv_sc_iter).second; - CGAL_assertion_msg((u == w) || (uv_hcl->size() == 1), "more than one constraint passing through the subconstraint" ); - } - // now u,v, and w are ordered along the polyline constraint + Context_list* vw_hcl = vw_sc_iter->second; + // AF: what is input() about??? if(vc.input()){ uc.input() = true; wc.input() = true; } - typename Sc_to_c_map::iterator vw_sc_iter = sc_to_c_map.find(make_edge(v, w)); - CGAL_assertion_msg( vw_sc_iter != sc_to_c_map.end(), "not a subconstraint" ); - Context_list* vw_hcl = vw_sc_iter->second; - CGAL_assertion_msg((u == w) || (vw_hcl->size() == 1), "more than one constraint passing through the subconstraint" ); - Vertex_list* vertex_list = uv_hcl->front().id().vl_ptr(); - CGAL_assertion_msg(vertex_list == vw_hcl->front().id().vl_ptr(), "subconstraints from different polyline constraints" ); - // Remove the list item which points to v - vertex_list->skip(vc.base()); - - if(u != w){ - // Remove the entries for [u,v] and [v,w] - sc_to_c_map.erase(uv_sc_iter); - sc_to_c_map.erase(vw_sc_iter); - delete vw_hcl; - // reuse other context list - sc_to_c_map[make_edge(u,w)] = uv_hcl; - }else{ - sc_to_c_map.erase(uv_sc_iter); - delete vw_hcl; + // Take contexts from the two context lists depending on the orientation of the constraints + // These are the contexts where current is either u or w + // remove from uv_hcl the contexts where current is not u + // remove from vw_hcl the contexts where current is not w + // splice into uv_hcl + typename Context_list::iterator it = uv_hcl->begin(); + while(it != uv_hcl->end()){ + if((*it->current()) != u){ + it = uv_hcl->erase(it); + }else{ + // Remove the list item which points to v + Vertex_list* vertex_list = it->id().vl_ptr(); + Vertex_it vc_in_context = it->current(); + vc_in_context = boost::next(vc_in_context); + vertex_list->skip(vc_in_context.base()); + ++it; + } } + it = vw_hcl->begin(); + while(it != vw_hcl->end()){ + if((*it->current()) != w){ + it = vw_hcl->erase(it); + }else{ + // Remove the list item which points to v + Vertex_list* vertex_list = it->id().vl_ptr(); + Vertex_it vc_in_context = it->current(); + vc_in_context = boost::next(vc_in_context); + vertex_list->skip(vc_in_context.base()); + ++it; + } + } + + uv_hcl->splice(uv_hcl->end(),*vw_hcl); + delete vw_hcl; + + sc_to_c_map.erase(uv_sc_iter); + sc_to_c_map.erase(vw_sc_iter); + + // reuse other context list + sc_to_c_map[make_edge(u,w)] = uv_hcl; } diff --git a/Triangulation_3/examples/Triangulation_3/CMakeLists.txt b/Triangulation_3/examples/Triangulation_3/CMakeLists.txt index 5453babb101..f7942bdfd5d 100644 --- a/Triangulation_3/examples/Triangulation_3/CMakeLists.txt +++ b/Triangulation_3/examples/Triangulation_3/CMakeLists.txt @@ -53,6 +53,14 @@ if(TARGET CGAL::TBB_support) target_link_libraries(parallel_insertion_in_delaunay_3 PUBLIC CGAL::TBB_support) target_link_libraries(sequential_parallel PUBLIC CGAL::TBB_support) + + if(BUILD_TESTING) + set_property(TEST + execution___of__parallel_insertion_and_removal_in_regular_3 + execution___of__parallel_insertion_in_delaunay_3 + execution___of__sequential_parallel + PROPERTY RUN_SERIAL 1) + endif() else() message(STATUS "NOTICE: a few examples require TBB and will not be compiled.") endif() diff --git a/Triangulation_3/include/CGAL/Regular_triangulation_3.h b/Triangulation_3/include/CGAL/Regular_triangulation_3.h index d927efad23b..34186b034a0 100644 --- a/Triangulation_3/include/CGAL/Regular_triangulation_3.h +++ b/Triangulation_3/include/CGAL/Regular_triangulation_3.h @@ -55,7 +55,6 @@ #include #endif -#include #include #include #include diff --git a/Triangulation_3/test/Triangulation_3/CMakeLists.txt b/Triangulation_3/test/Triangulation_3/CMakeLists.txt index 86f7889cdbe..c0c171ac10f 100644 --- a/Triangulation_3/test/Triangulation_3/CMakeLists.txt +++ b/Triangulation_3/test/Triangulation_3/CMakeLists.txt @@ -35,6 +35,13 @@ if(TARGET CGAL::TBB_support) test_regular_insert_range_with_info) target_link_libraries(${target} PUBLIC CGAL::TBB_support) endforeach() + if(BUILD_TESTING) + set_property(TEST + execution___of__test_delaunay_3 + execution___of__test_regular_3 + execution___of__test_regular_insert_range_with_info + PROPERTY RUN_SERIAL 1) + endif() endif() if(BUILD_TESTING) diff --git a/copyright b/copyright index cecd857d055..876931746d3 100644 --- a/copyright +++ b/copyright @@ -124,4 +124,3 @@ R = RU Groningen Width_3 E iostream ETIMU kdtree T - wininst ETIMU diff --git a/wininst/developer_scripts/CGAL.bmp b/wininst/developer_scripts/CGAL.bmp deleted file mode 100644 index ab1c3f16f2d..00000000000 Binary files a/wininst/developer_scripts/CGAL.bmp and /dev/null differ diff --git a/wininst/developer_scripts/DumpLogToFile.nsh b/wininst/developer_scripts/DumpLogToFile.nsh deleted file mode 100644 index ff7bc413e73..00000000000 --- a/wininst/developer_scripts/DumpLogToFile.nsh +++ /dev/null @@ -1,47 +0,0 @@ -# -# From: http://nsis.sourceforge.net/Dump_log_to_file -# - -!define LVM_GETITEMCOUNT 0x1004 -!define LVM_GETITEMTEXT 0x102D - -Function DumpLog - Exch $5 - Push $0 - Push $1 - Push $2 - Push $3 - Push $4 - Push $6 - - FindWindow $0 "#32770" "" $HWNDPARENT - GetDlgItem $0 $0 1016 - StrCmp $0 0 exit - FileOpen $5 $5 "w" - StrCmp $5 "" exit - SendMessage $0 ${LVM_GETITEMCOUNT} 0 0 $6 - System::Alloc ${NSIS_MAX_STRLEN} - Pop $3 - StrCpy $2 0 - System::Call "*(i, i, i, i, i, i, i, i, i) i \ - (0, 0, 0, 0, 0, r3, ${NSIS_MAX_STRLEN}) .r1" - loop: StrCmp $2 $6 done - System::Call "User32::SendMessageA(i, i, i, i) i \ - ($0, ${LVM_GETITEMTEXT}, $2, r1)" - System::Call "*$3(&t${NSIS_MAX_STRLEN} .r4)" - FileWrite $5 "$4$\r$\n" - IntOp $2 $2 + 1 - Goto loop - done: - FileClose $5 - System::Free $1 - System::Free $3 - exit: - Pop $6 - Pop $4 - Pop $3 - Pop $2 - Pop $1 - Pop $0 - Exch $5 -FunctionEnd \ No newline at end of file diff --git a/wininst/developer_scripts/EnvVarUpdate.nsh b/wininst/developer_scripts/EnvVarUpdate.nsh deleted file mode 100644 index 93fb025721a..00000000000 --- a/wininst/developer_scripts/EnvVarUpdate.nsh +++ /dev/null @@ -1,360 +0,0 @@ -/** - * EnvVarUpdate.nsh - * : Environmental Variables: append, prepend, and remove entries - * - * WARNING: If you use StrFunc.nsh header then include it before this file - * with all required definitions. This is to avoid conflicts - * - * Usage: - * ${EnvVarUpdate} "ResultVar" "EnvVarName" "Action" "RegLoc" "PathString" - * - * Credits: - * Version 1.0 - * * Cal Turney (turnec2) - * * Amir Szekely (KiCHiK) and e-circ for developing the forerunners of this - * function: AddToPath, un.RemoveFromPath, AddToEnvVar, un.RemoveFromEnvVar, - * WriteEnvStr, and un.DeleteEnvStr - * * Diego Pedroso (deguix) for StrTok - * * Kevin English (kenglish_hi) for StrContains - * * Hendri Adriaens (Smile2Me), Diego Pedroso (deguix), and Dan Fuhry - * (dandaman32) for StrReplace - * - * Version 1.1 (compatibility with StrFunc.nsh) - * * techtonik - * - * http://nsis.sourceforge.net/Environmental_Variables:_append%2C_prepend%2C_and_remove_entries - * - */ - - -!ifndef ENVVARUPDATE_FUNCTION -!define ENVVARUPDATE_FUNCTION -!verbose push -!verbose 3 -!include "LogicLib.nsh" -!include "WinMessages.NSH" -!include "StrFunc.nsh" - -; ---- Fix for conflict if StrFunc.nsh is already includes in main file ----------------------- -!macro _IncludeStrFunction StrFuncName - !ifndef ${StrFuncName}_INCLUDED - ${${StrFuncName}} - !endif - !ifndef Un${StrFuncName}_INCLUDED - ${Un${StrFuncName}} - !endif - !define un.${StrFuncName} "${Un${StrFuncName}}" -!macroend - -!insertmacro _IncludeStrFunction StrTok -!insertmacro _IncludeStrFunction StrStr -!insertmacro _IncludeStrFunction StrRep - -; ---------------------------------- Macro Definitions ---------------------------------------- -!macro _EnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString - Push "${EnvVarName}" - Push "${Action}" - Push "${RegLoc}" - Push "${PathString}" - Call EnvVarUpdate - Pop "${ResultVar}" -!macroend -!define EnvVarUpdate '!insertmacro "_EnvVarUpdateConstructor"' - -!macro _unEnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString - Push "${EnvVarName}" - Push "${Action}" - Push "${RegLoc}" - Push "${PathString}" - Call un.EnvVarUpdate - Pop "${ResultVar}" -!macroend -!define un.EnvVarUpdate '!insertmacro "_unEnvVarUpdateConstructor"' -; ---------------------------------- Macro Definitions end------------------------------------- - -;----------------------------------- EnvVarUpdate start---------------------------------------- -!define hklm_all_users 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' -!define hkcu_current_user 'HKCU "Environment"' - -!macro EnvVarUpdate UN - -Function ${UN}EnvVarUpdate - - Push $0 - Exch 4 - Exch $1 - Exch 3 - Exch $2 - Exch 2 - Exch $3 - Exch - Exch $4 - Push $5 - Push $6 - Push $7 - Push $8 - Push $9 - Push $R0 - - /* After this point: - ------------------------- - $0 = ResultVar (returned) - $1 = EnvVarName (input) - $2 = Action (input) - $3 = RegLoc (input) - $4 = PathString (input) - $5 = Orig EnvVar (read from registry) - $6 = Len of $0 (temp) - $7 = tempstr1 (temp) - $8 = Entry counter (temp) - $9 = tempstr2 (temp) - $R0 = tempChar (temp) */ - - ; Step 1: Read contents of EnvVarName from RegLoc - ; - ; R0 = "user" or "system" - - ; Check for empty EnvVarName - ${If} $1 == "" - SetErrors - DetailPrint "ERROR: EnvVarName is blank" - Goto EnvVarUpdate_Restore_Vars - ${EndIf} - - ; Check for valid Action - ${If} $2 != "A" - ${AndIf} $2 != "P" - ${AndIf} $2 != "R" - SetErrors - DetailPrint "ERROR: Invalid Action - must be A, P, or R" - Goto EnvVarUpdate_Restore_Vars - ${EndIf} - - ${If} $3 == HKLM - ReadRegStr $5 ${hklm_all_users} $1 ; Get EnvVarName from all users into $5 - StrCpy $R0 "user" - ${ElseIf} $3 == HKCU - ReadRegStr $5 ${hkcu_current_user} $1 ; Read EnvVarName from current user into $5 - StrCpy $R0 "system" - ${Else} - SetErrors - DetailPrint 'ERROR: Action is [$3] but must be "HKLM" or HKCU"' - Goto EnvVarUpdate_Restore_Vars - ${EndIf} - - IfErrors 0 +4 - MessageBox MB_OK|MB_ICONEXCLAMATION "The $R0 environment variable $1 seems empty, and cannot be modified; set it manually to $4" - DetailPrint "Could not read the $R0 environment variable $1; set it manually to $4" - Goto EnvVarUpdate_Restore_Vars - - ; Check for empty PathString - ${If} $4 == "" - SetErrors - DetailPrint "ERROR: PathString is blank" - Goto EnvVarUpdate_Restore_Vars - ${EndIf} - - ;;khc - here check if length is going to be greater then max string length - ;; and abort if so - also abort if original path empty - may mean - ;; it was too long as well- write message to say set it by hand - Push $6 - Push $7 - Push $8 - StrLen $7 $4 - StrLen $6 $5 - IntOp $8 $6 + $7 - ${If} $5 == "" - ${OrIf} $8 >= ${NSIS_MAX_STRLEN} - SetErrors - MessageBox MB_OK|MB_ICONEXCLAMATION "Current $R0 $1 length ($6) too long to modify in NSIS; set manually if needed" - DetailPrint "Current $R0 $1 length ($6) too long to modify in NSIS; set manually if needed" - Pop $8 - Pop $7 - Pop $6 - Goto EnvVarUpdate_Restore_Vars - ${EndIf} - Pop $8 - Pop $7 - Pop $6 - ;;khc - - ; Make sure we've got some work to do - ${If} $5 == "" - ${AndIf} $2 == "R" - SetErrors - DetailPrint "$1 is empty - Nothing to remove" - Goto EnvVarUpdate_Restore_Vars - ${EndIf} - - ; Step 2: Scrub EnvVar - ; - StrCpy $0 $5 ; Copy the contents to $0 - ; Remove spaces around semicolons (NOTE: spaces before the 1st entry or - ; after the last one are not removed here but instead in Step 3) - ${If} $0 != "" ; If EnvVar is not empty ... - ${Do} - ${${UN}StrStr} $7 $0 " ;" - ${If} $7 == "" - ${ExitDo} - ${EndIf} - ${${UN}StrRep} $0 $0 " ;" ";" ; Remove ';' - ${Loop} - ${Do} - ${${UN}StrStr} $7 $0 "; " - ${If} $7 == "" - ${ExitDo} - ${EndIf} - ${${UN}StrRep} $0 $0 "; " ";" ; Remove ';' - ${Loop} - ${Do} - ${${UN}StrStr} $7 $0 ";;" - ${If} $7 == "" - ${ExitDo} - ${EndIf} - ${${UN}StrRep} $0 $0 ";;" ";" - ${Loop} - - ; Remove a leading or trailing semicolon from EnvVar - StrCpy $7 $0 1 0 - ${If} $7 == ";" - StrCpy $0 $0 "" 1 ; Change ';' to '' - ${EndIf} - StrLen $6 $0 - IntOp $6 $6 - 1 - StrCpy $7 $0 1 $6 - ${If} $7 == ";" - StrCpy $0 $0 $6 ; Change ';' to '' - ${EndIf} - ; DetailPrint "Scrubbed $1: [$0]" ; Uncomment to debug - ${EndIf} - - /* Step 3. Remove all instances of the target path/string (even if "A" or "P") - $6 = bool flag (1 = found and removed PathString) - $7 = a string (e.g. path) delimited by semicolon(s) - $8 = entry counter starting at 0 - $9 = copy of $0 - $R0 = tempChar */ - - ${If} $5 != "" ; If EnvVar is not empty ... - StrCpy $9 $0 - StrCpy $0 "" - StrCpy $8 0 - StrCpy $6 0 - - ${Do} - ${${UN}StrTok} $7 $9 ";" $8 "0" ; $7 = next entry, $8 = entry counter - - ${If} $7 == "" ; If we've run out of entries, - ${ExitDo} ; were done - ${EndIf} ; - - ; Remove leading and trailing spaces from this entry (critical step for Action=Remove) - ${Do} - StrCpy $R0 $7 1 - ${If} $R0 != " " - ${ExitDo} - ${EndIf} - StrCpy $7 $7 "" 1 ; Remove leading space - ${Loop} - ${Do} - StrCpy $R0 $7 1 -1 - ${If} $R0 != " " - ${ExitDo} - ${EndIf} - StrCpy $7 $7 -1 ; Remove trailing space - ${Loop} - ${If} $7 == $4 ; If string matches, remove it by not appending it - StrCpy $6 1 ; Set 'found' flag - ${ElseIf} $7 != $4 ; If string does NOT match - ${AndIf} $0 == "" ; and the 1st string being added to $0, - StrCpy $0 $7 ; copy it to $0 without a prepended semicolon - ${ElseIf} $7 != $4 ; If string does NOT match - ${AndIf} $0 != "" ; and this is NOT the 1st string to be added to $0, - StrCpy $0 $0;$7 ; append path to $0 with a prepended semicolon - ${EndIf} ; - - IntOp $8 $8 + 1 ; Bump counter - ${Loop} ; Check for duplicates until we run out of paths - ${EndIf} - - ; Step 4: Perform the requested Action - ; - ${If} $2 != "R" ; If Append or Prepend - ${If} $6 == 1 ; And if we found the target - DetailPrint "Target is already present in $1. It will be removed and" - ${EndIf} - ${If} $0 == "" ; If EnvVar is (now) empty - StrCpy $0 $4 ; just copy PathString to EnvVar - ${If} $6 == 0 ; If found flag is either 0 - ${OrIf} $6 == "" ; or blank (if EnvVarName is empty) - DetailPrint "$1 was empty and has been updated with the target" - ${EndIf} - ${ElseIf} $2 == "A" ; If Append (and EnvVar is not empty), - StrCpy $0 $0;$4 ; append PathString - ${If} $6 == 1 - DetailPrint "appended to $1" - ${Else} - DetailPrint "Target was appended to $1" - ${EndIf} - ${Else} ; If Prepend (and EnvVar is not empty), - StrCpy $0 $4;$0 ; prepend PathString - ${If} $6 == 1 - DetailPrint "prepended to $1" - ${Else} - DetailPrint "Target was prepended to $1" - ${EndIf} - ${EndIf} - ${Else} ; If Action = Remove - ${If} $6 == 1 ; and we found the target - DetailPrint "Target was found and removed from $1" - ${Else} - DetailPrint "Target was NOT found in $1 (nothing to remove)" - ${EndIf} - ${If} $0 == "" - DetailPrint "$1 is now empty" - ${EndIf} - ${EndIf} - - ; Step 5: Update the registry at RegLoc with the updated EnvVar and announce the change - ; - ClearErrors - ${If} $3 == HKLM - WriteRegExpandStr ${hklm_all_users} $1 $0 ; Write it in all users section - ${ElseIf} $3 == HKCU - WriteRegExpandStr ${hkcu_current_user} $1 $0 ; Write it to current user section - ${EndIf} - - IfErrors 0 +4 - MessageBox MB_OK|MB_ICONEXCLAMATION "Could not write updated $1 to $3" - DetailPrint "Could not write updated $1 to $3" - Goto EnvVarUpdate_Restore_Vars - - ; "Export" our change - SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 - - EnvVarUpdate_Restore_Vars: - ; - ; Restore the user's variables and return ResultVar - Pop $R0 - Pop $9 - Pop $8 - Pop $7 - Pop $6 - Pop $5 - Pop $4 - Pop $3 - Pop $2 - Pop $1 - Push $0 ; Push my $0 (ResultVar) - Exch - Pop $0 ; Restore his $0 - -FunctionEnd - -!macroend ; EnvVarUpdate UN -!insertmacro EnvVarUpdate "" -!insertmacro EnvVarUpdate "un." -;----------------------------------- EnvVarUpdate end---------------------------------------- - -!verbose pop -!endif diff --git a/wininst/developer_scripts/TextLog.nsh b/wininst/developer_scripts/TextLog.nsh deleted file mode 100644 index d5acf247746..00000000000 --- a/wininst/developer_scripts/TextLog.nsh +++ /dev/null @@ -1,68 +0,0 @@ -# TextLog.nsh v1.1 - 2005-12-26 -# Written by Mike Schinkel [http://www.mikeschinkel.com/blog/] - -Var /GLOBAL __TextLog_FileHandle -Var /GLOBAL __TextLog_FileName -Var /GLOBAL __TextLog_State - -!define LogMsg '!insertmacro LogMsgCall' -!macro LogMsgCall _text - Call LogSetOn - Push "${_text}" - Call LogText - Call LogSetOff -!macroend - - -!define LogText '!insertmacro LogTextCall' -!macro LogTextCall _text - Push "${_text}" - Call LogText -!macroend - -Function LogText - Exch $0 ; pABC -> 0ABC - FileWrite $__TextLog_FileHandle "$0$\r$\n" - Pop $0 ; 0ABC -> ABC -FunctionEnd - -!define LogSetFileName '!insertmacro LogSetFileNameCall' -!macro LogSetFileNameCall _filename - Push "${_filename}" - Call LogSetFileName -!macroend - -Function LogSetFileName - Exch $0 ; pABC -> 0ABC - StrCpy $__TextLog_FileName "$0" - StrCmp $__TextLog_State "open" +1 +3 - Call LogSetOff - Call LogSetOn - Pop $0 ; 0ABC -> ABC -FunctionEnd - -!define LogSetOn '!insertmacro LogSetOnCall' -!macro LogSetOnCall - Call LogSetOn -!macroend - -Function LogSetOn - StrCmp $__TextLog_FileName "" +1 AlreadySet - StrCpy $__TextLog_FileName "$INSTDIR\install.log" -AlreadySet: - StrCmp $__TextLog_State "open" +2 - FileOpen $__TextLog_FileHandle "$__TextLog_FileName" a - FileSeek $__TextLog_FileHandle 0 END - StrCpy $__TextLog_State "open" -FunctionEnd - -!define LogSetOff '!insertmacro LogSetOffCall' -!macro LogSetOffCall - Call LogSetOff -!macroend - -Function LogSetOff - StrCmp $__TextLog_State "open" +1 +2 - FileClose $__TextLog_FileHandle - StrCpy $__TextLog_State "" -FunctionEnd \ No newline at end of file diff --git a/wininst/developer_scripts/WriteEnvStr.nsh b/wininst/developer_scripts/WriteEnvStr.nsh deleted file mode 100644 index 2cc863b3344..00000000000 --- a/wininst/developer_scripts/WriteEnvStr.nsh +++ /dev/null @@ -1,183 +0,0 @@ -# -# Taken from http://nsis.sourceforge.net/Setting_Environment_Variables -# User handling modified by Fernando Cacciola -# Laurent Rineau added un.DeleteEnvStr and adapted it to handle user. -# -!ifndef _WriteEnvStr_nsh -!define _WriteEnvStr_nsh - -# -# Macro definition added by Fernando Cacciola -# -!define WriteEnvStr "!insertmacro WriteEnvStr" -!macro WriteEnvStr name value all_users - Push ${name} - Push ${value} - Push ${all_users} - Call WriteEnvStr -!macroend - -!define un.DeleteEnvStr "!insertmacro un.DeleteEnvStr" -!macro un.DeleteEnvStr name all_users - Push ${name} - Push ${all_users} - Call un.DeleteEnvStr -!macroend - -!include WinMessages.nsh - -!define WriteEnvStr_RegKey_AllUsers 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' - -!define WriteEnvStr_RegKey_CurrentUser 'HKCU "Environment"' - -# -# WriteEnvStr - Writes an environment variable -# Note: Win9x systems requires reboot -# -# Example: -# Push "HOMEDIR" # name -# Push "C:\New Home Dir\" # value -# Push 1 (all users) or 0 (current user only) -# Call WriteEnvStr -# -Function WriteEnvStr - Exch $2 ; $2 all users? - Exch - Exch $1 ; $1 has environment variable value - Exch 2 - Exch $0 ; $0 has environment variable name - Push $3 - - Call IsNT - Pop $3 - StrCmp $3 1 WriteEnvStr_NT - ; Not on NT - StrCpy $3 $WINDIR 2 ; Copy drive of windows (c:) - FileOpen $3 "$3\autoexec.bat" a - FileSeek $3 0 END - FileWrite $3 "$\r$\nSET $0=$1$\r$\n" - FileClose $3 - SetRebootFlag true - Goto WriteEnvStr_done - - WriteEnvStr_NT: - StrCmp $2 1 AllUsers - WriteRegExpandStr ${WriteEnvStr_RegKey_CurrentUser} $0 $1 - Goto Written - AllUsers: - WriteRegExpandStr ${WriteEnvStr_RegKey_AllUsers} $0 $1 - Written: - SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 - - WriteEnvStr_done: - Pop $3 - Pop $2 - Pop $0 - Pop $1 -FunctionEnd - -# -# un.DeleteEnvStr - Removes an environment variable -# Note: Win9x systems requires reboot -# -# Example: -# Push "HOMEDIR" # name -# Push 1 (all users) or 0 (current user only) -# Call un.DeleteEnvStr -# -Function un.DeleteEnvStr - Exch $1 ; $1 all users? - Exch - Exch $0 ; $0 now has the name of the variable - Push $2 - Push $3 - Push $4 - Push $5 - Push $6 - - Call un.IsNT - Pop $2 - StrCmp $2 1 DeleteEnvStr_NT - ; Not on NT - StrCpy $2 $WINDIR 2 - FileOpen $2 "$2\autoexec.bat" r - GetTempFileName $5 - FileOpen $3 $5 w - StrCpy $0 "SET $0=" - SetRebootFlag true - - DeleteEnvStr_dosLoop: - FileRead $2 $4 - StrLen $6 $0 - StrCpy $6 $4 $6 - StrCmp $6 $0 DeleteEnvStr_dosLoop - StrCmp $6 "" DeleteEnvStr_dosLoopEnd - FileWrite $3 $4 - Goto DeleteEnvStr_dosLoop - - DeleteEnvStr_dosLoopEnd: - FileClose $3 - FileClose $2 - StrCpy $2 $WINDIR 2 - Delete "$2\autoexec.bat" - CopyFiles /SILENT $5 "$2\autoexec.bat" - Delete $5 - Goto DeleteEnvStr_done - - DeleteEnvStr_NT: - StrCmp $1 1 DelAllUsers - DeleteRegValue ${WriteEnvStr_RegKey_CurrentUser} $0 - Goto DelWritten - DelAllUsers: - DeleteRegValue ${WriteEnvStr_RegKey_AllUsers} $0 - DelWritten: - SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} \ - 0 "STR:Environment" /TIMEOUT=5000 - - DeleteEnvStr_done: - Pop $6 - Pop $5 - Pop $4 - Pop $3 - Pop $2 - Pop $1 - Pop $0 -FunctionEnd - -!ifndef IsNT_KiCHiK -!define IsNT_KiCHiK - -# -# [un.]IsNT - Pushes 1 if running on NT, 0 if not -# -# Example: -# Call IsNT -# Pop $0 -# StrCmp $0 1 +3 -# MessageBox MB_OK "Not running on NT!" -# Goto +2 -# MessageBox MB_OK "Running on NT!" -# -!macro IsNT UN -Function ${UN}IsNT - Push $0 - ReadRegStr $0 HKLM \ - "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion - StrCmp $0 "" 0 IsNT_yes - ; we are not NT. - Pop $0 - Push 0 - Return - - IsNT_yes: - ; NT!!! - Pop $0 - Push 1 -FunctionEnd -!macroend -!insertmacro IsNT "" -!insertmacro IsNT "un." - -!endif ; IsNT_KiCHiK - -!endif ; _WriteEnvStr_nsh diff --git a/wininst/developer_scripts/cgal.ico b/wininst/developer_scripts/cgal.ico deleted file mode 100644 index 8b074d58e5a..00000000000 Binary files a/wininst/developer_scripts/cgal.ico and /dev/null differ diff --git a/wininst/developer_scripts/cgal_very_small_FFFFFF.bmp b/wininst/developer_scripts/cgal_very_small_FFFFFF.bmp deleted file mode 100644 index 31c859b9ce7..00000000000 Binary files a/wininst/developer_scripts/cgal_very_small_FFFFFF.bmp and /dev/null differ diff --git a/wininst/developer_scripts/default_variants.ini b/wininst/developer_scripts/default_variants.ini deleted file mode 100644 index 3a60f973c27..00000000000 --- a/wininst/developer_scripts/default_variants.ini +++ /dev/null @@ -1,93 +0,0 @@ -[Settings] -NumFields=11 - -[Field 1] -Type=GroupBox -Left=0 -Right=-1 -Top=0 -Bottom=-5 -Text=Select default variants - -[Field 2] -Type=GroupBox -Left=5 -Right=100 -Top=10 -Bottom=-10 -Text=Compilers - -[Field 3] -Type=GroupBox -Left=105 -Right=-5 -Top=10 -Bottom=-10 -Text=Variants - -[Field 4] -Type=CheckBox -Left=10 -Top=22 -Right=95 -Bottom=32 -Text=Visual C++ 7.1 - -[Field 5] -Type=CheckBox -Left=10 -Top=35 -Right=95 -Bottom=45 -Text=Visual C++ 8.0 - -; -- Variants - -[Field 6] -Type=CheckBox -Left=110 -Top=22 -Right=-10 -Bottom=32 -Text=Multithread Debug - -[Field 7] -Type=CheckBox -Left=110 -Right=-15 -Top=35 -Bottom=45 -Text=Multithread - -[Field 8] -Type=CheckBox -Left=110 -Right=-10 -Top=48 -Bottom=58 -Text=Multithread, static runtime - -[Field 9] -Type=CheckBox -Left=110 -Right=-10 -Top=61 -Bottom=71 -Text=Multithread Debug, static runtime - -[Field 10] -Type=CheckBox -Left=110 -Right=-10 -Top=74 -Bottom=84 -Text=Single thread, static runtime - -[Field 11] -Type=CheckBox -Left=110 -Right=-10 -Top=87 -Bottom=97 -Text=Single thread Debug, static runtime - diff --git a/wininst/developer_scripts/environment_variables.ini b/wininst/developer_scripts/environment_variables.ini deleted file mode 100644 index deab1792eae..00000000000 --- a/wininst/developer_scripts/environment_variables.ini +++ /dev/null @@ -1,90 +0,0 @@ -[Settings] -NumFields=10 - -[Field 1] -Type=GroupBox -Left=0 -Right=-1 -Top=0 -Bottom=23 -Text=Select user - -[Field 2] -Type=RadioButton -Left=10 -Right=80 -Top=10 -Bottom=20 -Text=All users -State=0 - -[Field 3] -Type=RadioButton -Left=90 -Right=160 -Top=10 -Bottom=20 -Text=Current user -State=1 - -[Field 4] -Type=GroupBox -Left=0 -Right=-1 -Top=25 -Bottom=-1 -Text=Environment variables to set - -[Field 5] -Type=Label -Left=10 -Right=-10 -Top=40 -Bottom=50 -Text=Directory where CGAL has been installed. - - -[Field 6] -Type=CheckBox -Left=20 -Right=75 -Top=55 -Bottom=65 -Text=CGAL_DIR -State=1 - -[Field 7] -Type=Text -Left=20 -Right=-10 -Top=70 -Bottom=85 -Text= -Flags=READONLY - -[Field 8] -Type=Label -Left=80 -Right=-10 -Top=55 -Bottom=65 -Text= -Flags=DISABLED - -[Field 9] -Type=CheckBox -Left=10 -Right=-10 -Top=95 -Bottom=105 -Text=Add CGAL/auxiliary/gmp/lib to the PATH -State=1 - -[Field 10] -Type=Label -Left=10 -Right=-10 -Top=110 -Bottom=135 -Text=CGAL/auxiliary/gmp/lib contains DLL files. If you do not add this to the PATH, make sure to manually move the DLLs to a directory already in the PATH. -Flags=DISABLED diff --git a/wininst/developer_scripts/fixup_projects.ini b/wininst/developer_scripts/fixup_projects.ini deleted file mode 100644 index af0f5856c55..00000000000 --- a/wininst/developer_scripts/fixup_projects.ini +++ /dev/null @@ -1,27 +0,0 @@ -[Settings] -NumFields=3 - -[Field 1] -Type=GroupBox -Left=0 -Right=-1 -Top=0 -Bottom=-5 -Text=Post-install changes to Visual Studio project files - -[Field 2] -Type=CheckBox -Left=10 -Right=-10 -Top=20 -Bottom=30 -Text=Remove CGAL_USE_GMP from all installed project files -State=1 - -[Field 3] -Type=Label -Left=20 -Right=-10 -Top=35 -Bottom=45 -Text=(because MPFR/GMP has not been installed) diff --git a/wininst/developer_scripts/locate.zip b/wininst/developer_scripts/locate.zip deleted file mode 100644 index 372f1eda265..00000000000 Binary files a/wininst/developer_scripts/locate.zip and /dev/null differ diff --git a/wininst/developer_scripts/script_cgal.nsh b/wininst/developer_scripts/script_cgal.nsh deleted file mode 100644 index 210d2430b2c..00000000000 --- a/wininst/developer_scripts/script_cgal.nsh +++ /dev/null @@ -1,65 +0,0 @@ -;============================ -; Copyright 2007, 2008, 2009 GeometryFactory (France) -; Authors: Andreas Fabri (andreas.fabri@geometryfactrory.com), -; Fernando Cacciola (fernando.cacciola@geometryfactrory.com), -; Laurent Rineau (laurent.rineau@geometryfactory.com) -;============================ -; Some portions of this file have been derived from "boost.nsi", the Boost Windows Installer, contributed by www.boost-consulting.org. -; -; Copyright 2006 Daniel Wallin -; Copyright 2006 Eric Niebler -; Distributed under the Boost Software License, Version 1.0. (See -; accompanying file LICENSE_1_0.txt or copy at -; http://www.boost.org/LICENSE_1_0.txt) -;============================ - -;!define SkipFiles -;!define SkipSetEnvVar -;!define SkipDownload -!define ViaFTP - -Var Platform - -!ifdef ViaFTP - !define DownloadOK "OK" - !define DownloadAborted "cancel" -!else - !define DownloadOK "success" - !define DownloadAborted "cancel" -!endif - -!macro DownloadFileFrom SERVER SRC_FOLDER FILE TGT -!ifndef SkipDownload - !ifdef DebugLog - ${LogMsg} "Downloadimg ${SERVER}${SRC_FOLDER}${FILE} into ${TGT}\${FILE}" - !endif - !ifdef ViaFTP - inetc::get ${SERVER}${SRC_FOLDER}${FILE} ${TGT}\${FILE} - !else - NSISdl::download ${SERVER}${SRC_FOLDER}${FILE} ${TGT}\${FILE} - !endif - Pop $0 - ${If} "$0" == "OK" - DetailPrint "${FILE} downloaded successfully." - ${ElseIf} "$0" == "URL Parts Error" - DetailPrint "${FILE} downloaded successfully." - ${ElseIf} "$0" == "Terminated" - DetailPrint "${FILE} download CANCELLED." - ${ElseIf} "$0" == "Cancelled" - DetailPrint "${FILE} download CANCELLED." - ${Else} - MessageBox MB_OK "Unable to download ${SERVER}${SRC_FOLDER}${FILE}. Error: $0" - DetailPrint "ERROR $0: Unable to download ${SERVER}${SRC_FOLDER}${FILE}." - ${Endif} -!endif -!macroend - -!macro DownloadFile SRC_FOLDER FILE TGT - !insertmacro DownloadFileFrom ${FTP_SRC} ${SRC_FOLDER} ${FILE} ${TGT} -!macroend - -!macro Install_GMP_MPFR_bin PLATFORM - !insertmacro DownloadFile "auxiliary/${PLATFORM}/GMP/5.0.1/" "gmp-all-CGAL-3.9.zip" "$INSTDIR\auxiliary\gmp" - !insertmacro DownloadFile "auxiliary/${PLATFORM}/MPFR/3.0.0/" "mpfr-all-CGAL-3.9.zip" "$INSTDIR\auxiliary\gmp" -!macroend - diff --git a/wininst/developer_scripts/script_cgal.nsi b/wininst/developer_scripts/script_cgal.nsi deleted file mode 100644 index 4ebac61843a..00000000000 --- a/wininst/developer_scripts/script_cgal.nsi +++ /dev/null @@ -1,472 +0,0 @@ -;=========================== -; Copyright 2007, 2008 GeometryFactory (France) -; Author: Andreas Fabri (andreas.fabri@geometryfactrory.com), Fernando Cacciola (fernando.cacciola@geometryfactrory.com) -;============================ -; Some portions of this file have been derived from "boost.nsi", the Boost Windows Installer, contributed by www.boost-consulting.org. -; -; Copyright 2006 Daniel Wallin -; Copyright 2006 Eric Niebler -; Distributed under the Boost Software License, Version 1.0. (See -; accompanying file LICENSE_1_0.txt or copy at -; http://www.boost.org/LICENSE_1_0.txt) -;============================ - - -!include "MUI.nsh" -!include "Sections.nsh" -!include "LogicLib.nsh" -!include "Locate.nsh" -!include "WriteEnvStr.nsh" -!include "EnvVarUpdate.nsh" -!include "x64.nsh" - -;!define DebugLog - -!ifdef DebugLog - !include "TextLog.nsh" -!endif - -!include "script_cgal.nsh" - -!define CGAL_SRC "CGAL-4.8" -!define FTP_SRC "https://cgal.geometryfactory.com/CGAL/precompiled_libs/" - -;-------------------------------- -; General -;-------------------------------- - - ;Name and file - Name "${CGAL_SRC}" - - !ifdef FetchLocal - OutFile "${CGAL_SRC}-Full-Setup.exe" - !else - OutFile "${CGAL_SRC}-Setup.exe" - !endif - - ;Default installation folder: C:\dev\CGAL-4.8 - ; See also .onInit - Installdir "" - - - ;Get installation folder from registry if available - InstallDirRegKey HKCU "Software\${CGAL_SRC}" "" - - BrandingText "The CGAL Project and GeometryFactory - Installer created with NSIS." - - VIProductVersion "4.8.0.0" - VIAddVersionKey "ProductName" "CGAL Windows Installer" - VIAddVersionKey "CompanyName" "The CGAL Project and GeometryFactory" - VIAddVersionKey "LegalCopyright" "© The CGAL Project and GeometryFactory" - VIAddVersionKey "FileDescription" "Windows Installer for CGAL" - VIAddVersionKey "FileVersion" "4.8" - -;-------------------------------- -; Variables -;-------------------------------- - - Var SetCGAL_DIR - Var RegLoc - Var Add_GMP_LIB_DIR_to_PATH - -;-------------------------------- -; Interface Settings -;-------------------------------- - - !define MUI_ICON "cgal.ico" - !define MUI_UNICON "cgal.ico" - !define MUI_HEADERIMAGE - !define MUI_HEADERIMAGE_BITMAP_NOSTRETCH - !define MUI_HEADERIMAGE_UNBITMAP_NOSTRETCH - - !define MUI_HEADERIMAGE_BITMAP "cgal_very_small_FFFFFF.bmp" ; optional - !define MUI_HEADERIMAGE_UNBITMAP "cgal_very_small_FFFFFF.bmp" ; optional - - !define MUI_FINISHPAGE_NOAUTOCLOSE - - !define MUI_ABORTWARNING - - !define MUI_WELCOMEFINISHPAGE_BITMAP Zirkel.bmp - !define MUI_WELCOMEFINISHPAGE_BITMAP_NOSTRETCH - !define MUI_UNWELCOMEFINISHPAGE_BITMAP Zirkel.bmp - !define MUI_UNWELCOMEFINISHPAGE_BITMAP_NOSTRETCH - - !define MUI_COMPONENTSPAGE_SMALLDESC - - !define MUI_WELCOMEPAGE_TEXT "This downloads ${CGAL_SRC} to your machine." - - !define MUI_FINISHPAGE_TITLE "Downloading finished" - - !define MUI_FINISHPAGE_TEXT "You have downloaded CGAL successfully. Please continue the installation, reading the installation instructions." - - !define MUI_FINISHPAGE_LINK "Installation instructions" - - !define MUI_FINISHPAGE_LINK_LOCATION "https://www.cgal.org/download/windows.html" - -;-------------------------------- -; Pages -;-------------------------------- - - !insertmacro MUI_PAGE_WELCOME - !insertmacro MUI_PAGE_LICENSE "${CGAL_SRC}\LICENSE" - - !insertmacro MUI_PAGE_COMPONENTS - - ; A page where the user can specify a default variant configuration (taken from the boost installer) - Page custom VariantsPage - - !insertmacro MUI_PAGE_DIRECTORY - - ; A page where the user can check/uncheck the environment variables - ; used to specify paths in vcproj files to be added. - Page custom envarsPage - - !insertmacro MUI_PAGE_INSTFILES - - !insertmacro MUI_PAGE_FINISH - - !insertmacro MUI_UNPAGE_WELCOME - !insertmacro MUI_UNPAGE_CONFIRM - !insertmacro MUI_UNPAGE_INSTFILES - !insertmacro MUI_UNPAGE_FINISH - -;-------------------------------- -; Languages - - !insertmacro MUI_LANGUAGE "English" - -;-------------------------------- -; Sections -;-------------------------------- - - -;-------------------------------- -Section "!Main CGAL" MAIN_Idx - -!ifndef SkipFiles - SectionIn RO - SetOutPath "$INSTDIR\auxiliary" - File /nonfatal /r "${CGAL_SRC}\auxiliary\*.*" - SetOutPath "$INSTDIR\cmake" - File /r "${CGAL_SRC}\cmake\*.*" - SetOutPath "$INSTDIR\doc_html" - File /r "${CGAL_SRC}\doc_html\*.*" - SetOutPath "$INSTDIR\include" - File /r "${CGAL_SRC}\include\*.*" - SetOutPath "$INSTDIR\lib" - File /r "${CGAL_SRC}\lib\*.*" - SetOutPath "$INSTDIR\scripts" - File /r "${CGAL_SRC}\scripts\*.*" - SetOutPath "$INSTDIR\src" - File /r "${CGAL_SRC}\src\*.*" - SetOutPath "$INSTDIR\demo\icons" - File /r "${CGAL_SRC}\demo\icons\*.*" - SetOutPath "$INSTDIR\demo\resources" - File /r "${CGAL_SRC}\demo\resources\*.*" - - SetOutPath "$INSTDIR" - File "${CGAL_SRC}\AUTHORS" - File "${CGAL_SRC}\CGALConfig.cmake" - File "${CGAL_SRC}\CHANGES.md" - File "${CGAL_SRC}\CMakeLists.txt" - File "${CGAL_SRC}\INSTALL.md" - File "${CGAL_SRC}\LICENSE" - File "${CGAL_SRC}\LICENSE.BSL" - File "${CGAL_SRC}\LICENSE.LGPL" - File "${CGAL_SRC}\LICENSE.GPL" - File "${CGAL_SRC}\LICENSE.RFL" - File "${CGAL_SRC}\VERSION" - File ".\cgal.ico" -!endif - - ; Write uninstall informations - ; http://nsis.sourceforge.net/Add_uninstall_information_to_Add/Remove_Programs - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${CGAL_SRC}" \ - "DisplayName" "${CGAL_SRC} -- Computational Geometry Algorithms Library, version 4.8" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${CGAL_SRC}" \ - "UninstallString" "$\"$INSTDIR\Uninstall.exe$\"" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${CGAL_SRC}" \ - "QuietUninstallString" "$\"$INSTDIR\Uninstall.exe$\" /S" - - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${CGAL_SRC}" \ - "NoModify" 1 - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${CGAL_SRC}" \ - "NoRepair" 1 - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${CGAL_SRC}" \ - "InstallLocation" "$\"$INSTDIR$\"" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${CGAL_SRC}" \ - "DisplayIcon" "$\"$INSTDIR\cgal.ico$\"" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${CGAL_SRC}" \ - "Publisher" "The CGAL Project and GeometryFactory" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${CGAL_SRC}" \ - "URLInfoAbout" "https://www.cgal.org/" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${CGAL_SRC}" \ - "DisplayedVersion" "4.8.0" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${CGAL_SRC}" \ - "CGALUninstallRegLoc" "$RegLoc" - - ;Create uninstaller - WriteUninstaller "$INSTDIR\Uninstall.exe" -SectionEnd -;-------------------------------- - -;-------------------------------- -Section "CGAL Examples and Demos" SAMPLES_Idx - -!ifndef SkipFiles - SetOutPath "$INSTDIR\examples" - File /r "${CGAL_SRC}\examples\*.*" - SetOutPath "$INSTDIR\demo" - File /r "${CGAL_SRC}\demo\*.*" -!endif -SectionEnd - -; Download and install GMP and MPFR binaries. -; Depend only on the platform (one variant per platform) -Section "GMP and MPFR precompiled libs" GMP_LIB_Idx - !ifndef FetchLocal - !insertmacro Install_GMP_MPFR_bin "$Platform" - !endif -SectionEnd - - -;-------------------------------- - - -Section /o "HTML Manuals" DOC_Idx - !ifndef FetchLocal - !insertmacro DownloadFileFrom "https://cgal.geometryfactory.com/" "CGAL/4.8/Manual/" "cgal_manual.zip" "$INSTDIR\doc_html" - !endif -SectionEnd - -Section "-Unzip" - - ${locate::Open} "$INSTDIR" "/D=0 /X=zip" $0 - ${If} $0 <> 0 - ${Do} - ${locate::Find} $0 $1 $2 $3 $4 $5 $6 - ${If} "$1" != "" - ZipDLL::extractall $1 $2 - Pop $7 - ${If} "$7" == "success" - Delete $1 - ${EndIf} - ${EndIf} - ${LoopUntil} "$1" == "" - ${EndIf} - ${locate::Close} $0 - ${locate::Unload} - -SectionEnd - -;-------------------------------- -;Uninstaller Section - -Section "Uninstall" - - ;ADD YOUR OWN FILES HERE... - - Delete "$INSTDIR\Uninstall.exe" - - RMDir /r "$INSTDIR" - - ReadRegStr $RegLoc HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${CGAL_SRC}" \ - "CGALUninstallRegLoc" - - DeleteRegKey /ifempty HKCU "Software\${CGAL_SRC}" - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${CGAL_SRC}" - - ${un.EnvVarUpdate} $0 "PATH" "R" $RegLoc "$INSTDIR\auxiliary\gmp\lib" - ${If} $RegLoc == HKLM - ${un.DeleteEnvStr} "CGAL_DIR" 1 - ${Else} - ${un.DeleteEnvStr} "CGAL_DIR" 0 - ${EndIf} - -SectionEnd - - - - -;-------------------------------- -;Descriptions - - ;Language strings - LangString DESC_MAIN ${LANG_ENGLISH} "The main components of the CGAL Library." - LangString DESC_SAMPLES ${LANG_ENGLISH} "The CGAL demos and examples, for which you need Qt 5 in order to build them (and Qt 3 for some)." - LangString DESC_GMP_LIB ${LANG_ENGLISH} "The precompiled GMP and MPFR libraries (needed for exact constructions)." - LangString DESC_DOC ${LANG_ENGLISH} "The HTML manuals." - LangString DESC_ENVSET ${LANG_ENGLISH} "already set" - - ;Assign language strings to sections - !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN - !insertmacro MUI_DESCRIPTION_TEXT ${MAIN_Idx} $(DESC_MAIN) - !insertmacro MUI_DESCRIPTION_TEXT ${SAMPLES_Idx} $(DESC_SAMPLES) - !insertmacro MUI_DESCRIPTION_TEXT ${GMP_LIB_Idx} $(DESC_GMP_LIB) - !insertmacro MUI_DESCRIPTION_TEXT ${DOC_Idx} $(DESC_DOC) - !insertmacro MUI_FUNCTION_DESCRIPTION_END - - -;-------------------------------- -; Functions -;-------------------------------- - -Function .onInit - - # Setup the default installation dir - ${If} $InstDir == "" ; /D= was not used on the command line - StrCpy $InstDir "C:\dev\${CGAL_SRC}" - ${EndIf} - - !ifdef DebugLog - ${LogSetFileName} "${CGAL_SRC}_install_log.txt" - ${LogSetOn} - !endif - - StrCpy $Platform "win32" - - # the plugins dir is automatically deleted when the installer exits - InitPluginsDir - File /oname=$PLUGINSDIR\splash.bmp ".\CGAL.bmp" - advsplash::show 1000 600 400 -1 $PLUGINSDIR\splash - - !insertmacro MUI_INSTALLOPTIONS_EXTRACT "variants.ini" - !insertmacro MUI_INSTALLOPTIONS_EXTRACT "environment_variables.ini" - -FunctionEnd - - -Function .onInstSuccess - - ${If} $SetCGAL_DIR != "" - ; RegLoc can be either HKLM (all users) or HKCU (current user). - ${If} $RegLoc == HKLM - ${WriteEnvStr} "CGAL_DIR" $SetCGAL_DIR 1 - ${Else} - ${WriteEnvStr} "CGAL_DIR" $SetCGAL_DIR 0 - ${Endif} - ${EndIf} - - ${If} $Add_GMP_LIB_DIR_to_PATH = 1 - ; Append "$INSTDIR\auxiliary\gmp\lib" to the PATH. - ; RegLoc can be either HKLM (all users) or HKCU (current user). - ; The return value goes to $0 - ${EnvVarUpdate} $0 "PATH" "A" $RegLoc "$INSTDIR\auxiliary\gmp\lib" - ${EndIf} - -FunctionEnd - -Function VariantsPage - - !insertmacro MUI_HEADER_TEXT "Select platform" "Choose the platform for precompiled libraries." - !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "variants.ini" - !insertmacro MUI_INSTALLOPTIONS_SHOW - - !insertmacro MUI_INSTALLOPTIONS_READ $0 "variants.ini" "Field 1" "State" - ${If} $0 = 1 - StrCpy $Platform "win32" - ${Else} - StrCpy $Platform "x64" - ${Endif} - -FunctionEnd - -# Disables the env var checkbox # FN and textbox # FN+1 -!macro UncheckEnvStrCheckbox FN - !insertmacro MUI_INSTALLOPTIONS_WRITE "environment_variables.ini" "Field ${FN}" "State" "0" -!macroend - -!macro CheckEnvStrCheckbox FN - !insertmacro MUI_INSTALLOPTIONS_WRITE "environment_variables.ini" "Field ${FN}" "State" "1" -!macroend - -!macro DisableEnvStrCheckbox FN - !insertmacro MUI_INSTALLOPTIONS_WRITE "environment_variables.ini" "Field ${FN}" "Flags" "DISABLED" -!macroend - -!macro EnableEnvStrCheckbox FN - !insertmacro MUI_INSTALLOPTIONS_WRITE "environment_variables.ini" "Field ${FN}" "Flags" "" -!macroend - -# Disables the env var checkbox # FN -!macro SetEnvStrValueSlot FN VAL - !insertmacro MUI_INSTALLOPTIONS_WRITE "environment_variables.ini" "Field ${FN}" "State" "${VAL}" -!macroend - -!macro SetEnvStrLabel FN VAL - !insertmacro MUI_INSTALLOPTIONS_WRITE "environment_variables.ini" "Field ${FN}" "Text" "${VAL}" -!macroend - - -Function envarsPage - - Push $0 - Push $1 - Push $2 - Push $3 - Push $4 - Push $5 - - - !insertmacro MUI_HEADER_TEXT "Setting Environment Variables" "Choose whether to set or not the following environment variables" - - ReadEnvStr $1 "CGAL_DIR" # $1 = existing value for CGAL_DIR - - !insertmacro SetEnvStrValueSlot 7 $INSTDIR - !insertmacro SetEnvStrValueSlot 7 $INSTDIR - - ${If} $1 != "" - StrCpy $3 "($(DESC_ENVSET): $1 )" - !insertmacro UncheckEnvStrCheckbox 6 - !insertmacro SetEnvStrLabel 8 $3 - ${Endif} - - SectionGetText ${GMP_LIB_Idx} $2 - - SectionGetFlags ${GMP_LIB_Idx} $1 - IntOp $2 $1 & ${SF_SELECTED} - - ${If} $2 == 0 - !insertmacro UncheckEnvStrCheckbox 9 - !insertmacro DisableEnvStrCheckbox 9 - ${Else} - !insertmacro CheckEnvStrCheckbox 9 - !insertmacro EnableEnvStrCheckbox 9 - ${Endif} - - !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "environment_variables.ini" - - !insertmacro MUI_INSTALLOPTIONS_SHOW_RETURN - Pop $0 - ${If} "$0" = "success" - # PROCESSING - Installs selected environment variables - - !insertmacro MUI_INSTALLOPTIONS_READ $3 "environment_variables.ini" "Field 2" "State" # $3=Is ALL USERS selected - - ${If} $3 == 1 - StrCpy $RegLoc "HKLM" - ${Else} - StrCpy $RegLoc "HKCU" - ${EndIf} - - !insertmacro MUI_INSTALLOPTIONS_READ $3 "environment_variables.ini" "Field 6" "State" # CGAL_DIR checkbox - !insertmacro MUI_INSTALLOPTIONS_READ $4 "environment_variables.ini" "Field 7" "State" # CGAL_DIR value - ${If} $3 == 1 - StrCpy $SetCGAL_DIR $4 - ${EndIF} - - !insertmacro MUI_INSTALLOPTIONS_READ $5 "environment_variables.ini" "Field 9" "State" # Add to PATH checkbox - ${If} $5 == 1 - StrCpy $Add_GMP_LIB_DIR_to_PATH 1 - ${EndIF} - - ${EndIf} - - Pop $5 - Pop $4 - Pop $3 - Pop $2 - Pop $1 - Pop $0 - -FunctionEnd diff --git a/wininst/developer_scripts/variants.ini b/wininst/developer_scripts/variants.ini deleted file mode 100644 index 2b838dbff97..00000000000 --- a/wininst/developer_scripts/variants.ini +++ /dev/null @@ -1,19 +0,0 @@ -[Settings] -NumFields=2 - -[Field 1] -Type=RadioButton -Text=32-bits -Left=10 -Right=-10 -Top=2 -Bottom=12 -State=1 - -[Field 2] -Type=RadioButton -Text=64-bits -Left=10 -Right=-10 -Top=15 -Bottom=24 diff --git a/wininst/developer_scripts/zirkel.bmp b/wininst/developer_scripts/zirkel.bmp deleted file mode 100644 index e4ef234b0b2..00000000000 Binary files a/wininst/developer_scripts/zirkel.bmp and /dev/null differ diff --git a/wininst/package_info/wininst/copyright b/wininst/package_info/wininst/copyright deleted file mode 100644 index a35c66ade4c..00000000000 --- a/wininst/package_info/wininst/copyright +++ /dev/null @@ -1,5 +0,0 @@ -Utrecht University (The Netherlands), -ETH Zurich (Switzerland), -INRIA Sophia-Antipolis (France), -Max-Planck-Institute Saarbruecken (Germany), -Tel-Aviv University (Israel). diff --git a/wininst/package_info/wininst/dependencies b/wininst/package_info/wininst/dependencies deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/wininst/package_info/wininst/description.txt b/wininst/package_info/wininst/description.txt deleted file mode 100644 index 083e45cb0e2..00000000000 --- a/wininst/package_info/wininst/description.txt +++ /dev/null @@ -1 +0,0 @@ -Win32-specific installation procedures diff --git a/wininst/package_info/wininst/maintainer b/wininst/package_info/wininst/maintainer deleted file mode 100644 index 4f45ddcd216..00000000000 --- a/wininst/package_info/wininst/maintainer +++ /dev/null @@ -1 +0,0 @@ -Andreas Fabri